You need to enable JavaScript to run this app. 如何爬取整站域名下所有PDF链接 修复BeautifulSoup爬虫现有缺陷
优惠活动
大模型
产品
解决方案
定价
更多

如何爬取整站域名下所有PDF链接 修复BeautifulSoup爬虫现有缺陷

问题根因

现有代码的核心错误有3个:

  • 提取域名的逻辑硬编码了.com后缀,而你要爬的站点是.de后缀,导致域名提取完全错误,内链外链判断逻辑完全失效
  • 没有做相对路径转绝对路径的处理,所有相对路径的链接都会被误判
  • 仅爬取了首页一个页面,没有递归遍历全站所有内链
实现方案

不需要引入额外复杂库,用Python标准库urllib.parse配合requests+BeautifulSoup即可实现,核心需要新增两个逻辑:相对路径转绝对路径、全站广度优先遍历+去重。

修改后完整代码
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from collections import deque

if __name__ == '__main__':
    # 配置参数
    base_url = "https://www.aurednik.de/"
    parsed_base = urlparse(base_url)
    base_domain = parsed_base.netloc  # 自动提取域名,无需硬编码后缀
    
    # 待爬队列、已爬集合、PDF链接集合
    to_crawl = deque([base_url])
    crawled = set()
    pdf_links = set()
    
    # 请求头避免被站点反爬拦截
    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"
    }
    
    while to_crawl:
        current_url = to_crawl.popleft()
        if current_url in crawled:
            continue
        # 标记为已爬
        crawled.add(current_url)
        print(f"正在爬取: {current_url}")
        
        try:
            resp = requests.get(current_url, headers=headers, timeout=10)
            resp.raise_for_status()
            # 非HTML内容跳过解析
            if 'text/html' not in resp.headers.get('Content-Type', ''):
                # 直接判断是否为PDF
                if current_url.lower().endswith('.pdf'):
                    pdf_links.add(current_url)
                continue
        except Exception as e:
            print(f"爬取失败 {current_url}: {str(e)}")
            continue
        
        soup = BeautifulSoup(resp.text, 'lxml')
        for a_tag in soup.find_all('a', href=True):
            href = a_tag['href'].strip()
            # 转成绝对路径
            abs_href = urljoin(current_url, href)
            # 去掉锚点避免重复爬取同一页面
            abs_href = abs_href.split('#')[0]
            parsed_href = urlparse(abs_href)
            
            # 筛选同域名内链
            if parsed_href.netloc == base_domain:
                # 先判断是不是PDF
                if abs_href.lower().endswith('.pdf'):
                    pdf_links.add(abs_href)
                # 不是PDF且没爬过的加入待爬队列
                elif abs_href not in crawled and abs_href not in to_crawl:
                    to_crawl.append(abs_href)
    
    # 输出结果
    print("\n=== 所有PDF链接 ===")
    for pdf in pdf_links:
        print(pdf)
代码说明
  • 用urlparse自动提取站点域名,兼容所有后缀的域名,不会出现硬编码.com的错误
  • 用urljoin自动把相对路径拼接成绝对路径,避免路径判断错误
  • 用广度优先遍历+去重逻辑遍历全站所有内链,不会漏爬页面
  • 对每个链接先判断是不是PDF后缀,是就直接存入结果,不是的同域名内链加入爬取队列
  • 加了UA请求头避免被站点反爬拦截,加了超时和异常处理避免爬取中断

内容的提问来源于stack exchange,提问作者x89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 21:39:02