如何使用Puppeteer下载网页中的目标PDF文件?
解决Puppeteer下载PDF文档的问题
针对你遇到的PDF下载困境,我整理了两种实用方案,帮你顺利获取目标文档:
方案一:先获取PDF链接再下载
你提到想抓取页面里的src链接,其实新打开的PDF页面本身的URL就是下载地址,步骤如下:
- 获取PDF的直接链接
当点击链接打开新页面后,通过evaluate方法提取当前页面的URL(因为新页面加载的就是PDF文件):
const newPagePromise = new Promise(x => browser.once("targetcreated", target => x(target.page()))); await page.click("#gvDocketResult_ctl0" + rows.length + "_hlDocumentRedacted"); const newPage = await newPagePromise; // 等待页面完全加载 await newPage.waitForNavigation({ waitUntil: 'networkidle2' }); // 提取PDF的下载链接 const pdfUrl = await newPage.evaluate(() => document.location.href); console.log("获取到PDF链接:", pdfUrl);
- 用Node.js工具下载到本地
拿到链接后,用Node.js内置的https和fs模块直接下载,这种方式更灵活可控:
const https = require('https'); const fs = require('fs'); const path = require('path'); // 自定义保存路径和文件名 const savePath = path.join('/Users/me/Desktop', `document_${rows.length}.pdf`); https.get(pdfUrl, (response) => { const fileStream = fs.createWriteStream(savePath); response.pipe(fileStream); fileStream.on('finish', () => { fileStream.close(); console.log("PDF已成功保存到:", savePath); }); }).on('error', (err) => { console.error("下载失败:", err.message); }); // 记得关闭新打开的页面 await newPage.close();
方案二:配置Puppeteer下载行为直接保存
你之前尝试的Page.setDownloadBehavior思路是对的,但可能时机没把握好。正确的做法是在新页面初始化时就配置下载规则:
const newPagePromise = new Promise(x => browser.once("targetcreated", async target => { const newPage = await target.page(); // 给新页面设置下载权限和保存路径 await newPage._client.send("Page.setDownloadBehavior", { behavior: "allow", downloadPath: "/Users/me/Desktop", // 如果网站需要身份验证,加上这句保留凭证 // credentials: "include" }); x(newPage); })); await page.click("#gvDocketResult_ctl0" + rows.length + "_hlDocumentRedacted"); const newPage = await newPagePromise; // 监听下载完成事件,确保文件保存成功 const downloadFinish = new Promise(resolve => { newPage.on('download', async (downloadItem) => { const finalPath = await downloadItem.path(); console.log("下载完成,文件路径:", finalPath); resolve(); }); }); await downloadFinish; await newPage.close();
补充细节
如果PDF是通过页面里的embed或iframe加载的,需要调整链接提取逻辑:
const pdfUrl = await newPage.evaluate(() => { const embedEl = document.querySelector('embed'); const iframeEl = document.querySelector('iframe'); // 优先取embed/iframe的src,没有则用当前页面URL return embedEl?.src || iframeEl?.src || document.location.href; });
另外要确保downloadPath对应的文件夹存在,且你的Node进程有写入权限。
内容的提问来源于stack exchange,提问作者Nicholas Jennings
相关产品推荐
相关产品推荐

