Puppeteer如何下载内嵌PDF?能否设置Chromium默认下载PDF
问题描述
我访问一个带有PDF文件链接的页面,点击链接会打开新标签页,页面内容如下:
<html> <head></head> <body style="height: 100%; width: 100%; overflow: hidden; margin:0px; background-color: rgb(38, 38, 38);"> <embed name="B4133D167D3B030DC294D8CA8F6FC5FE" style="position:absolute; left: 0; top: 0;" width="100%" height="100%" src="about:blank" type="application/pdf" internalid="B4133D167D3B030DC294D8CA8F6FC5FE"> </body> </html>
这个embed标签内嵌了我需要下载的PDF。目前我只能手动修改chrome://settings/content/pdfDocuments设置为默认下载PDF,但每次重启浏览器后设置都会重置,且无法在无头模式下测试此方案。我尝试使用--print-to-pdf参数启动Chromium,但没有成功。现咨询:
- Puppeteer能否启动Chromium时设置默认下载PDF且无需绑定配置文件?
- 是否有其他使用Puppeteer下载内嵌PDF的方法?
解决方案
1. 无需绑定配置文件,用Puppeteer设置默认下载PDF
可以通过Puppeteer的page.setUserPreferences()方法配置Chrome首选项,强制PDF文件下载而非内嵌预览,无需依赖持久化配置文件,且支持无头模式。示例代码:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox'] // 按需添加,适配特定运行环境 }); const page = await browser.newPage(); // 配置PDF下载偏好 await page.setUserPreferences({ download: { prompt_for_download: false, // 跳过下载确认弹窗 default_directory: '/your/custom/download/path' // 指定下载目录 }, plugins: { always_open_pdf_externally: true // 强制PDF下载,不内嵌预览 } }); // 访问目标页面并触发PDF链接点击 await page.goto('your-target-page-url'); await page.click('#pdf-link'); // 替换为实际PDF链接的选择器 // 等待下载完成并保存 const download = await page.waitForEvent('download'); await download.saveAs('/path/to/save/your.pdf'); await browser.close(); })();
每次Puppeteer启动新浏览器实例时,该配置会自动生效,无需手动修改浏览器设置。
2. 其他下载内嵌PDF的方法
如果上述偏好设置不生效,可尝试以下两种方案:
方法一:拦截网络请求获取PDF真实URL
浏览器加载embed内的PDF时会发送网络请求,通过Puppeteer拦截该请求获取真实地址后直接下载:
const puppeteer = require('puppeteer'); const fs = require('fs'); (async () => { const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); let pdfUrl = ''; // 开启请求拦截 await page.setRequestInterception(true); page.on('request', (request) => { // 捕获PDF资源请求 if (request.resourceType() === 'document' && request.url().endsWith('.pdf')) { pdfUrl = request.url(); } request.continue(); }); // 打开包含embed的新标签页 await page.goto('url-of-the-new-tab-with-embed'); if (pdfUrl) { // 请求PDF内容并保存到本地 const response = await page.goto(pdfUrl); const pdfBuffer = await response.buffer(); fs.writeFileSync('/path/to/save/pdf-file.pdf', pdfBuffer); } await browser.close(); })();
方法二:获取embed标签的真实PDF源
部分场景下embed的src会动态加载(初始为about:blank),可等待页面加载完成后,通过evaluate()获取真实src再下载:
const puppeteer = require('puppeteer'); const fs = require('fs'); (async () => { const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); // 等待页面完全加载 await page.goto('url-of-the-new-tab-with-embed', { waitUntil: 'networkidle0' }); // 提取embed标签的真实PDF地址 const pdfSrc = await page.evaluate(() => { const embed = document.querySelector('embed[type="application/pdf"]'); return embed?.src || ''; }); if (pdfSrc && pdfSrc !== 'about:blank') { const response = await page.goto(pdfSrc); const pdfBuffer = await response.buffer(); fs.writeFileSync('/path/to/save/pdf-file.pdf', pdfBuffer); } await browser.close(); })();
内容的提问来源于stack exchange,提问作者gothaf
相关产品推荐
相关产品推荐

