如何用Python 2.7或JavaScript实现带认证的下载链接文件下载?
没问题,我来帮你搞定这个需求!针对Python 2.7的限制,咱们可以用requests库来处理登录认证和下载流程,同时从响应头里提取文件名实现重命名;如果用JavaScript的话,Puppeteer是绝佳选择,能模拟真实浏览器操作,完美适配点击下载链接的场景,还能轻松获取并修改文件名。
Python 2.7 实现方案
核心思路
- 维持登录会话:受密码保护的网站通常用会话Cookie保持登录状态,所以先完成登录请求,拿到有效会话。
- 请求下载接口:下载链接一般是触发下载的接口而非文件直链,用登录后的会话请求这个接口,再从响应头里解析文件名。
- 保存并命名文件:根据提取到的文件名保存PDF,也可以自定义文件名。
代码示例
首先安装Python2.7兼容的requests版本:
pip install requests==2.27.1 # 这个版本支持Python2.7
然后是完整代码:
import requests from requests.auth import HTTPBasicAuth import re # 初始化会话,维持登录状态 session = requests.Session() # --- 两种登录场景二选一 --- # 场景1:网站用HTTP基础认证(浏览器弹出登录框那种) # session.auth = HTTPBasicAuth('你的用户名', '你的密码') # 场景2:网站用表单登录(输入用户名密码提交表单) login_url = 'https://example.com/login' # 替换成实际登录页URL login_data = { 'username': '你的用户名', 'password': '你的密码', # 多数网站需要csrf_token,先访问登录页获取 } # 先爬取登录页拿到csrf_token login_page = session.get(login_url) csrf_match = re.search(r'<input name="csrf_token" value="(.*?)">', login_page.text) if csrf_match: login_data['csrf_token'] = csrf_match.group(1) # 发送登录请求并验证是否成功 login_response = session.post(login_url, data=login_data) if '欢迎回来' not in login_response.text: # 替换成登录成功后的标识文本 print('登录失败,请检查用户名密码或登录参数') exit() # 请求下载链接 download_url = 'https://example.com/download/pdf/123' # 替换成实际下载链接 # stream=True适合大文件,避免一次性加载到内存 download_response = session.get(download_url, stream=True) # 从响应头提取文件名 filename = 'default.pdf' if 'Content-Disposition' in download_response.headers: disposition = download_response.headers['Content-Disposition'] # 匹配带引号/不带引号、UTF-8编码的文件名格式 name_match = re.search(r'filename(?:\*?=UTF-8\'\')?["\']?([^"\']+)["\']?', disposition) if name_match: # Python2.7需要把字节串解码成unicode filename = name_match.group(1).decode('utf-8') # 保存文件 with open(filename, 'wb') as f: for chunk in download_response.iter_content(chunk_size=1024): if chunk: f.write(chunk) print(f'文件已成功保存为:{filename}')
JavaScript 实现方案(基于 Puppeteer)
核心思路
Puppeteer能模拟真实Chrome浏览器的操作,完美处理需要点击下载链接的场景,还能监听下载事件,获取原始文件名并自定义重命名。
代码示例
先安装依赖:
npm install puppeteer@19.11.1 # 这个版本支持较旧Node环境,适配下载场景
然后是完整代码:
const puppeteer = require('puppeteer'); const fs = require('fs'); const path = require('path'); (async () => { // 设置下载目录 const downloadDir = path.resolve(__dirname, 'pdf_downloads'); if (!fs.existsSync(downloadDir)) { fs.mkdirSync(downloadDir); } // 启动浏览器,可设置headless: true开启无头模式 const browser = await puppeteer.launch({ headless: false, defaultViewport: null, args: [ '--disable-notifications', `--download-path=${downloadDir}` ] }); const page = await browser.newPage(); // 1. 完成登录 await page.goto('https://example.com/login'); // 替换成实际登录页 // 填写用户名密码,替换成实际页面的选择器 await page.type('#username-input', '你的用户名'); await page.type('#password-input', '你的密码'); // 点击登录按钮 await page.click('#submit-login'); // 等待登录完成,比如等待登录后才出现的元素 await page.waitForSelector('#user-avatar'); // 替换成登录成功标识元素的选择器 // 2. 监听下载事件并点击下载链接 const downloadFinish = new Promise((resolve) => { page.on('download', async (downloadItem) => { // 获取原始文件名 const originalName = downloadItem.suggestedFilename(); // 自定义新文件名,比如加时间戳 const newName = `pdf_${Date.now()}_${originalName}`; const savePath = path.join(downloadDir, newName); // 保存文件到指定路径 await downloadItem.saveAs(savePath); console.log(`文件已保存为:${savePath}`); resolve(); }); }); // 点击下载链接,替换成实际下载按钮的选择器 await page.click('#download-pdf-btn'); // 等待下载完成 await downloadFinish; // 关闭浏览器 await browser.close(); })();
注意事项
- Python2.7的
requests已停止官方维护,后续有机会建议升级到Python3,但当前方案完全适配2.7需求。 - 表单登录时,一定要通过浏览器开发者工具(Network面板)查看实际请求参数,比如csrf_token、隐藏字段等,确保登录请求参数正确。
- Puppeteer的元素选择器需要根据目标网站的HTML结构调整,确保能准确定位到输入框、按钮等元素。
内容的提问来源于stack exchange,提问作者Iexist
相关产品推荐
相关产品推荐

