
本教程详细介绍了如何使用Python从ASP网站下载PDF文件,并根据HTML `` 标签的显示文本来命名本地文件。通过`requests`库处理HTTP请求和`BeautifulSoup`解析HTML,我们能够准确提取下载链接和用户友好的文件名,解决了直接使用URL文件名不直观的问题。文章涵盖了环境设置、HTML解析、URL处理、文件下载与保存等关键步骤,并提供了完整的示例代码和注意事项。
在自动化数据抓取和文件下载的场景中,我们经常需要从网站上下载文件,并以一种更具描述性或用户友好的方式来命名这些文件,而不是简单地沿用URL中自带的文件名。特别是在处理动态生成的页面或链接时,HTML <a> 标签的文本内容往往能提供比URL本身更清晰的文件描述。本教程将以从ASP网站下载PDF文件为例,详细讲解如何利用Python实现这一目标。
在开始之前,我们需要安装一些必要的Python库。requests库用于处理HTTP请求,而BeautifulSoup(通常与解析器如lxml或html.parser配合使用)则用于解析HTML内容。
pip install requests beautifulsoup4 lxml
接下来,导入所需的模块:
立即学习“Python免费学习笔记(深入)”;
import os import requests from bs4 import BeautifulSoup
许多网站,尤其是ASP站点,会通过POST请求来动态加载内容。我们需要模拟这种请求以获取包含PDF链接的HTML页面。这通常涉及构建请求的URL、headers以及请求体(payload)。
# 目标网站的基础URL
base_url = "https://www.svpo.nl/curriculum.asp"
# 模拟浏览器发送请求的User-Agent,以避免被网站识别为爬虫
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}
# 示例:定义需要请求的课程和科目
klassen = ['1e klas']
vakken = ['Wiskunde']
# 定义文件保存的根目录
output_root_path = r'c:ooks' # 使用原始字符串避免反斜杠转义问题
# 循环处理每个课程和科目
for klas in klassen:
for vak in vakken:
# 构建当前科目和课程的输出路径
current_output_path = os.path.join(output_root_path, klas, vak)
# 如果目录不存在,则创建它。exist_ok=True 避免目录已存在时报错
os.makedirs(current_output_path, exist_ok=True)
# 构建POST请求的payload
payload = {'vak': vak, 'klas_en_schoolsoort': klas}
# 发送POST请求获取页面内容
try:
response = requests.post(base_url, data=payload, headers=headers, timeout=10)
response.raise_for_status() # 检查HTTP请求是否成功 (200 OK)
print(f"成功获取 {klas} - {vak} 的页面内容。")
except requests.exceptions.RequestException as e:
print(f"获取 {klas} - {vak} 页面内容失败: {e}")
continue # 跳过当前科目,处理下一个获取到页面HTML内容后,我们需要使用BeautifulSoup来解析它,找到所有指向PDF文件的链接,并提取其文本内容作为文件名。
# 使用lxml解析器解析HTML内容
soup = BeautifulSoup(response.text, "lxml")
# 查找所有带有'href'属性的<a>标签
all_links = soup.find_all('a', {'href': True})
for link_tag in all_links:
pdf_url = link_tag.get('href')
# 检查链接是否以'.pdf'结尾(不区分大小写)
if pdf_url and pdf_url.lower().endswith('.pdf'):
# 提取<a>标签的文本内容作为文件名
# 例如:<a href="https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c">Chapter 3 - Weird science</a> -> "Chapter 3 - Weird science"
display_name = link_tag.text.strip()
# 处理URL路径和文件名
# 网站URL中可能使用反斜杠,HTTP URL应使用正斜杠
pdf_url = pdf_url.replace('\', '/')
# 构造本地保存的文件名。注意添加'.pdf'后缀
# 示例: "Chapter 3 - Weird science" -> "Chapter 3 - Weird science.pdf"
filename = f"{display_name}.pdf"
# 构建完整的本地文件路径
full_file_path = os.path.join(current_output_path, filename)
print(f"发现PDF: {display_url},将保存为: {full_file_path}")
# 下载并保存PDF文件
try:
pdf_response = requests.get(pdf_url, stream=True, timeout=15) # 使用stream=True处理大文件
pdf_response.raise_for_status()
with open(full_file_path, 'wb') as f:
for chunk in pdf_response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"成功下载并保存: {filename}")
except requests.exceptions.RequestException as e:
print(f"下载 {pdf_url} 失败: {e}")
except IOError as e:
print(f"保存文件 {full_file_path} 失败: {e}")
print('---')以下是整合了所有步骤的完整Python脚本,用于从ASP网站下载PDF文件并根据链接文本自定义文件名。
import os
import requests
from bs4 import BeautifulSoup
def download_pdfs_with_custom_names(base_url, output_root_path, klassen, vakken):
"""
从指定ASP网站下载PDF文件,并根据HTML链接文本自定义文件名。
Args:
base_url (str): 目标网站的URL。
output_root_path (str): 文件保存的根目录。
klassen (list): 包含课程名称的列表。
vakken (list): 包含科目名称的列表。
"""
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}
print(f"开始从 {base_url} 下载PDF文件https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c")
for klas in klassen:
for vak in vakken:
current_output_path = os.path.join(output_root_path, klas, vak)
os.makedirs(current_output_path, exist_ok=True)
print(f"
--- 处理 {klas} - {vak} ---")
payload = {'vak': vak, 'klas_en_schoolsoort': klas}
# 1. 发送POST请求获取页面内容
try:
response = requests.post(base_url, data=payload, headers=headers, timeout=10)
response.raise_for_status() # 检查HTTP请求是否成功
print(f"成功获取 {klas} - {vak} 的页面内容。")
except requests.exceptions.RequestException as e:
print(f"获取 {klas} - {vak} 页面内容失败: {e}")
continue
# 2. 解析HTML内容提取PDF链接和名称
soup = BeautifulSoup(response.text, "lxml")
all_links = soup.find_all('a', {'href': True})
pdfs_found = False
for link_tag in all_links:
pdf_url = link_tag.get('href')
if pdf_url and pdf_url.lower().endswith('.pdf'):
pdfs_found = True
display_name = link_tag.text.strip()
# 统一URL中的斜杠,确保HTTP请求正确
pdf_url = pdf_url.replace('\', '/')
# 构造本地保存的文件名
filename = f"{display_name}.pdf"
# 清理文件名中可能存在的非法字符(Windows/Linux路径限制)
# 这是一个简单的清理,更健壮的方案可能需要正则表达式
# 这里假设 display_name 已经相对干净
invalid_chars = '<>:"/\|?*'
for char in invalid_chars:
filename = filename.replace(char, '_')
full_file_path = os.path.join(current_output_path, filename)
print(f" - 发现PDF: {pdf_url}")
print(f" 将保存为: {full_file_path}")
# 3. 下载并保存PDF文件
try:
# 使用 stream=True 和 iter_content 处理大文件,节省内存
pdf_response = requests.get(pdf_url, stream=True, timeout=15)
pdf_response.raise_for_status()
with open(full_file_path, 'wb') as f:
for chunk in pdf_response.iter_content(chunk_size=8192):
f.write(chunk)
print(f" 成功下载并保存: {filename}")
except requests.exceptions.RequestException as e:
print(f" 下载 {pdf_url} 失败: {e}")
except IOError as e:
print(f" 保存文件 {full_file_path} 失败: {e}")
if not pdfs_found:
print(f" - 未在 {klas} - {vak} 页面中找到任何PDF链接。")
print("
所有PDF下载任务完成。")
# 配置参数并运行脚本
if __name__ == "__main__":
target_base_url = "https://www.svpo.nl/curriculum.asp"
output_directory = r'c:ooks' # Windows路径建议使用原始字符串
# 示例课程和科目列表,可以根据需要扩展
target_klassen = ['1e klas']
target_vakken = ['Wiskunde']
# target_vakken = ['Engels','Aardrijkskunde','Economie', 'Filosofie','Frans', 'Geschiedenis',
# 'Nask', 'Natuurkunde', 'Nederlands', 'Scheikunde', 'Spaans', 'Wiskunde',
# 'Biologie', 'Duits', 'Grieks','Latijn','Leesmateriaal',
# 'Loopbaanorientatie','NLT']
download_pdfs_with_custom_names(target_base_url, output_directory, target_klassen, target_vakken)本教程详细演示了如何使用Python的requests和BeautifulSoup库,从动态生成的网页中提取PDF下载链接和用户友好的显示名称,并将其保存到本地文件系统。通过自定义文件名,我们不仅提高了下载文件的可读性,也展示了Python在网页内容自动化处理方面的强大能力。掌握这些技术,您可以更高效地进行网络数据抓取和文件管理。
以上就是使用Python从网站下载PDF并根据HTML文本自定义文件名的详细内容,更多请关注php中文网其它相关文章!
HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号