本文介绍一种可靠、可定制的 python 方案,通过解析 html 页面提取 pdf 链接并逐个下载,解决 wget 不支持 http 环境下通配符(*)导致批量下载失败的问题。
本文介绍一种可靠、可定制的 python 方案,通过解析 html 页面提取 pdf 链接并逐个下载,解决 wget 不支持 http 环境下通配符(*)导致批量下载失败的问题。
在 Web 抓取场景中,wget 的 * 通配符仅适用于 FTP 或本地文件系统,HTTP/HTTPS 协议本身不支持服务端通配符匹配——因此直接构造如 .../1520-0493_2003_131_*.co_2.pdf 的 URL 必然返回 500 错误或 404。真正可行的方案是:先获取目标页面的 HTML 结构,从中解析出所有 PDF 对应的原始 XML 或文章路径,再按规则拼接为有效 PDF 下载地址。
以下是一个基于 requests 和 lxml 的稳健实现(无需 Selenium,轻量高效):
import requests
from lxml import html
import os
# 设置请求头,模拟浏览器访问,避免被反爬拦截
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
# 目标期刊期号页面(含文章列表)
base_url = "https://journals.ametsoc.org/view/journals/mwre/131/5/mwre.131.issue-5.xml"
print("正在获取文章列表页...")
response = requests.get(base_url, headers=headers, timeout=30)
response.raise_for_status()
# 解析 HTML,定位每篇文章的 XML 链接(通常为 <h1><a class="c-Button--link"> 标签)
tree = html.fromstring(response.text)
xml_links = tree.xpath("//h1/a[@class='c-Button--link']/@href")
if not xml_links:
raise RuntimeError("未找到任何文章链接,请检查页面结构或 CSS 选择器是否更新")
print(f"共发现 {len(xml_links)} 篇文章,开始生成 PDF 下载地址...")
# 创建 pdfs/ 子目录存放文件(避免污染当前目录)
os.makedirs("pdfs", exist_ok=True)
downloaded = 0
for xml_link in xml_links:
try:
# 将 XML 路径中的 .xml 替换为 .pdf,并拼接下载基础域名
pdf_path = xml_link.replace(".xml", ".pdf")
pdf_url = f"https://journals.ametsoc.org/downloadpdf{pdf_path}"
# 获取 PDF 响应
pdf_resp = requests.get(pdf_url, headers=headers, timeout=60)
pdf_resp.raise_for_status()
# 验证响应内容类型是否为 PDF(关键防护)
content_type = pdf_resp.headers.get("content-type", "").lower()
if "application/pdf" not in content_type and "pdf" not in content_type:
print(f"⚠️ 跳过非PDF响应: {pdf_url} (Content-Type: {content_type})")
continue
# 提取文件名(保留原始命名,更利于文献管理)
filename = os.path.basename(pdf_path)
filepath = os.path.join("pdfs", filename)
# 写入二进制 PDF 文件
with open(filepath, "wb") as f:
f.write(pdf_resp.content)
print(f"✅ 已下载: {filename}")
downloaded += 1
except Exception as e:
print(f"❌ 下载失败 {xml_link}: {e}")
print(f"\n? 完成!成功下载 {downloaded}/{len(xml_links)} 个 PDF 文件。")</a></h1>
? 关键注意事项:
- 反爬策略:务必设置 User-Agent,部分学术站点会拒绝无头请求;若持续失败,可添加 --random-wait 类似逻辑(如 time.sleep(random.uniform(5, 15)))。
- 路径可靠性:本例依赖 XML → PDF 的固定路径转换(.xml → .pdf),若网站改版,需用开发者工具检查实际 PDF 链接规律(如查看 Download PDF)。
- 错误处理:代码已包含 raise_for_status() 和 MIME 类型校验,避免保存空文件或 HTML 错误页。
- 法律与伦理:请遵守网站 robots.txt 及《Terms of Use》,单次批量下载建议控制速率(如每 10 秒 1 个),避免对服务器造成压力。
该方法灵活、可控且易于扩展(例如增加并发下载、自动重试、元数据 CSV 记录等),是学术资源合规采集的推荐实践。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











