如何从网站批量下载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,建议添加适当的延迟。
重要提醒
- 遵守网站规则:很多图书馆或学术站点禁止批量下载,先查看网站的
robots.txt和使用条款,避免违规。 - 版权合规:下载的PDF仅用于个人学习研究,禁止传播或商用。
内容的提问来源于stack exchange,提问作者ZQH11




