如何使用Python提取跳转页中的PDF链接并实现自动下载
实现方案
原代码问题定位
- 锚文本匹配逻辑鲁棒性不足:使用精确等值匹配
text=['HERE', 'here', 'Here']时,无法识别前后带空格、标点的锚文本节点,容易漏抓目标链接 - 路径处理缺失:直接将抓取到的href值传给
urlopen,遇到相对路径(如/imo/media/doc/xxx.pdf)时会直接访问失败 - 链接提取无规则:跳转页面后无差别抓取所有
<a>标签的href,没有对PDF资源做定向过滤,容易混入无关链接
可复用的非硬编码实现代码
import urllib3 import re from urllib.request import urlopen from urllib.parse import urljoin from bs4 import BeautifulSoup # 关闭请求告警 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # 配置基础域名,用于拼接相对路径 BASE_DOMAIN = "https://www.murphy.senate.gov" START_URL = "https://www.murphy.senate.gov/newsroom/press-releases/murphy-blumenthal-introduce-legislation-to-create-a-national-green-bank-thousands-of-clean-energy-jobs" # 1. 解析初始新闻页,定位锚文本为"here"的跳转链接 soup = BeautifulSoup(urlopen(START_URL), "html.parser") # 模糊匹配所有大小写、带前后空白的here锚文本 here_link = soup.find( "a", href=True, text=re.compile(r"\s*here\s*", re.IGNORECASE) )["href"] # 自动将相对路径拼接为绝对路径 absolute_here_url = urljoin(BASE_DOMAIN, here_link) # 2. 访问跳转链接,自动定位PDF资源 resp = urlopen(absolute_here_url) # 直接判断当前响应是否为PDF文件 if resp.headers.get("Content-Type", "").endswith("pdf"): target_pdf_url = absolute_here_url else: # 解析跳转后的HTML页,匹配后缀为.pdf的链接 sub_soup = BeautifulSoup(resp.read(), "html.parser") pdf_href = sub_soup.find("a", href=re.compile(r"\.pdf$", re.IGNORECASE))["href"] target_pdf_url = urljoin(BASE_DOMAIN, pdf_href) # 后续可直接通过target_pdf_url下载PDF文件
核心规则说明
- 无硬编码适配:不写死PDF的具体文件名、目录路径,仅通过
.pdf后缀的通用规则匹配目标资源,同站点其他新闻页的PDF提取逻辑可直接复用 - 路径自动兼容:所有跳转链接通过
urljoin自动补全域名,不需要手动判断抓取到的href是相对路径还是绝对路径,避免访问失败 - 锚文本模糊匹配:使用忽略大小写的正则匹配"here"锚点,兼容页面内
Here、HERE、前后带空格/标点的格式,解决原代码精确匹配漏抓的问题 - 响应类型预判:进入跳转链接后先通过响应头的Content-Type判断当前资源是否为PDF,减少不必要的HTML解析开销
内容的提问来源于stack exchange,提问作者scraping_paint
相关产品推荐
相关产品推荐

