You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从网站批量下载PDF?含Python实现及密码保护站点可行性问询

批量下载网站PDF文件(含密码保护站点方案)

嘿,我来一步步帮你搞定这些问题——不管是普通公开网站还是需要账号密码的图书馆站点,Python都能实现批量下载PDF的需求,下面分情况给你详细拆解:

1. 无密码保护网站的PDF批量下载

如果目标网站的PDF是公开可访问的,核心思路就是先爬取页面上所有的PDF链接,再逐个下载保存。用Python来做的话,借助requests(发送HTTP请求)和BeautifulSoup(解析HTML页面)这两个库就能轻松实现。

步骤&代码示例

首先安装依赖库:

pip install requests beautifulsoup4

然后运行以下代码(记得替换目标网站URL和保存目录):

import requests
from bs4 import BeautifulSoup
import os

# 替换成你的目标网站URL
target_url = "https://example.com/pdf-collection"
# 保存PDF的本地文件夹
save_dir = "downloaded_pdfs"
os.makedirs(save_dir, exist_ok=True)

# 伪装浏览器请求头,避免被网站反爬拦截
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

# 获取目标页面内容
try:
    response = requests.get(target_url, headers=headers)
    response.raise_for_status()  # 如果请求失败直接抛出错误
except Exception as e:
    print(f"获取页面失败: {str(e)}")
    exit()

# 解析页面,提取所有PDF链接
soup = BeautifulSoup(response.text, "html.parser")
pdf_links = soup.find_all("a", href=lambda href: href and href.endswith(".pdf"))

# 批量下载PDF文件
for link in pdf_links:
    pdf_url = link["href"]
    # 处理相对路径的链接,转成完整URL
    if not pdf_url.startswith("http"):
        pdf_url = requests.compat.urljoin(target_url, pdf_url)
    
    try:
        pdf_response = requests.get(pdf_url, headers=headers)
        pdf_response.raise_for_status()
        
        # 提取文件名并保存
        filename = os.path.join(save_dir, pdf_url.split("/")[-1])
        with open(filename, "wb") as f:
            f.write(pdf_response.content)
        print(f"✅ 成功下载: {filename}")
    except Exception as e:
        print(f"❌ 下载失败 {pdf_url}: {str(e)}")

2. 密码保护站点(如图书馆)的批量下载

如果你有站点的合法访问权限和账号密码,依然可以实现批量下载——核心是保持登录会话状态,让请求带着认证后的Cookie访问受保护的页面。

步骤&代码示例

这类站点通常需要先通过表单登录,我们用requests.Session()来管理会话,自动保存登录后的Cookie:

import requests
from bs4 import BeautifulSoup
import os
import time

# 配置你的站点信息
login_url = "https://library.example.com/login"  # 登录页面URL
target_pdf_page = "https://library.example.com/protected-pdfs"  # 受保护的PDF列表页面
save_dir = "library_pdfs"
username = "你的账号"
password = "你的密码"
os.makedirs(save_dir, exist_ok=True)

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

# 创建会话对象,自动维护登录状态
session = requests.Session()

# 先获取登录页面,提取可能需要的CSRF令牌(部分站点会验证)
try:
    login_page = session.get(login_url, headers=headers)
    login_page.raise_for_status()
    soup = BeautifulSoup(login_page.text, "html.parser")
    # 提取CSRF令牌(字段名根据实际页面调整,比如csrfmiddlewaretoken、token等)
    csrf_token = soup.find("input", {"name": "csrfmiddlewaretoken"})["value"]
except Exception as e:
    print(f"获取登录页面失败: {str(e)}")
    exit()

# 构造登录表单数据(字段名要和页面的登录表单一致,可通过浏览器F12查看)
login_data = {
    "username": username,
    "password": password,
    "csrfmiddlewaretoken": csrf_token  # 如果站点不需要可以删除这一行
}

# 发送登录请求
try:
    login_response = session.post(login_url, data=login_data, headers=headers)
    login_response.raise_for_status()
    # 验证是否登录成功(根据站点返回的内容判断,比如是否包含"欢迎"字样)
    if "欢迎回来" not in login_response.text:
        print("登录失败,请检查账号密码或表单字段名")
        exit()
    print("✅ 登录成功!")
except Exception as e:
    print(f"登录请求失败: {str(e)}")
    exit()

# 登录后访问PDF列表页面,提取链接
try:
    pdf_page = session.get(target_pdf_page, headers=headers)
    pdf_page.raise_for_status()
    pdf_soup = BeautifulSoup(pdf_page.text, "html.parser")
    pdf_links = pdf_soup.find_all("a", href=lambda href: href and href.endswith(".pdf"))
except Exception as e:
    print(f"获取PDF列表页面失败: {str(e)}")
    exit()

# 批量下载PDF(加延迟避免触发反爬)
for link in pdf_links:
    pdf_url = link["href"]
    if not pdf_url.startswith("http"):
        pdf_url = requests.compat.urljoin(target_pdf_page, pdf_url)
    
    try:
        pdf_response = session.get(pdf_url, headers=headers)
        pdf_response.raise_for_status()
        
        filename = os.path.join(save_dir, pdf_url.split("/")[-1])
        with open(filename, "wb") as f:
            f.write(pdf_response.content)
        print(f"✅ 成功下载: {filename}")
        time.sleep(1)  # 延迟1秒,避免请求过于频繁
    except Exception as e:
        print(f"❌ 下载失败 {pdf_url}: {str(e)}")

关键注意事项

  • 登录表单的字段名一定要和目标站点一致,你可以通过浏览器开发者工具(F12→网络→提交登录时查看Form Data)确认。
  • 如果站点有验证码,可能需要额外处理(比如手动输入或使用OCR工具,但请遵守站点规则)。
  • 不要频繁发送请求,避免被封IP,建议添加适当的延迟。

重要提醒

  1. 遵守网站规则:很多图书馆或学术站点禁止批量下载,先查看网站的robots.txt和使用条款,避免违规。
  2. 版权合规:下载的PDF仅用于个人学习研究,禁止传播或商用。

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

火山引擎 最新活动