使用Puppeteer下载点击后新开窗口PDF的替代实现方案咨询
Puppeteer 跳过新窗口PDF预览直接下载的实现方案
这里有三种成熟的实现方式,都可以避免手动操作新窗口内的保存按钮:
方案1:监听新窗口事件直接抓取PDF内容
点击PDF跳转链接前提前监听弹窗事件,拿到新页面的PDF地址后直接请求内容存本地,适配绝大多数场景:
await page.goto('https://www.website.com/Dashboard.aspx'); // 动态传入ID以进入目标页面 await page.type('#searchBox_ID' ,ids.RequestID); await page.click('#buttonCLick'); await page.waitForNavigation(); await page.waitForSelector('#PdfFile_Selector'); // 同时监听弹窗事件和执行点击操作,避免漏捕获新窗口 const [newPage] = await Promise.all([ page.waitForEvent('popup'), page.click('#PdfFile_Selector') ]) // 等待新页面加载完成 await newPage.waitForLoadState(); // 获取PDF的实际访问地址 const pdfUrl = newPage.url(); // 请求PDF二进制内容直接写入本地 const pdfBuffer = await page.goto(pdfUrl).then(res => res.buffer()); require('fs').writeFileSync('./目标文件.pdf', pdfBuffer); // 关闭临时新页面 await newPage.close();
方案2:配置浏览器参数让PDF自动下载
启动Puppeteer时禁用内置PDF预览器,让PDF文件直接走下载流程,无需处理新窗口:
const browser = await puppeteer.launch({ headless: 'new', // 建议使用新无头模式兼容性更好 acceptDownloads: true, args: [ '--disable-pdf-viewer', '--disable-extensions-exclude=r/ndmjckmmomfelkdaffckcegldplgehbm' // Chrome内置PDF预览器扩展固定ID ], preferences: { 'download.default_directory': './你的下载存储路径', // 自行替换为实际路径 'download.prompt_for_download': false, // 关闭下载提示弹窗 'plugins.always_open_pdf_externally': true, // PDF直接下载不预览 'download.directory_upgrade': true } }) // 后续原有业务逻辑不需要改动,点击#PdfFile_Selector后PDF会自动下载到指定目录
方案3:提取登录态直接请求PDF地址
如果PDF地址规则可预判,可以直接提取当前页面的Cookie,用HTTP客户端单独请求PDF:
// 前面业务逻辑执行完成后,先获取当前页面全量Cookie const cookies = await page.cookies(); const cookieStr = cookies.map(item => `${item.name}=${item.value}`).join('; '); // 替换为实际PDF地址,带上Cookie请求即可拿到文件内容 const axios = require('axios'); const res = await axios.get('https://www.website.com/你的PDF地址', { headers: { Cookie: cookieStr }, responseType: 'arraybuffer' }); require('fs').writeFileSync('./目标文件.pdf', res.data);
选型建议
- 如果PDF地址是动态生成无固定规则:优先选方案1
- 如果是批量下载大量PDF:优先选方案2,省去每个文件处理新窗口的开销
- 如果PDF地址规则固定,且需要和其他自动化流程解耦:优先选方案3
内容的提问来源于stack exchange,提问作者Muhammad Asad Chohan
相关产品推荐
相关产品推荐

