如何使用 puppeteer 和 Node js 为 pdf 页面生成屏幕截图
Posted
技术标签:
【中文标题】如何使用 puppeteer 和 Node js 为 pdf 页面生成屏幕截图【英文标题】:How to generate screenshots for pdf pages using puppeteer and Node js 【发布时间】:2019-09-30 08:49:54 【问题描述】:我正在使用 puppeteer 和 node js 创建一个屏幕截图生成器。它适用于普通网页,但对于 pdf 页面,每次运行时它总是给出相同的错误
这是代码(https://github.com/GoogleChrome/puppeteer 的第一个示例)
const puppeteer = require('puppeteer');
(async () =>
try
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf');
await page.screenshot( path: 'example.png' );
await browser.close();
catch (err)
console.log(err);
)();
我得到的错误
Error: net::ERR_ABORTED at https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf
at navigate (C:\MEAN\puppeteer-demo\node_modules\puppeteer\lib\FrameManager.js:121:37)
at process._tickCallback (internal/process/next_tick.js:68:7)
-- ASYNC --
at Frame.<anonymous> (C:\MEAN\puppeteer-demo\node_modules\puppeteer\lib\helper.js:110:27)
at Page.goto (C:\MEAN\puppeteer-demo\node_modules\puppeteer\lib\Page.js:629:49)
at Page.<anonymous> (C:\MEAN\puppeteer-demo\node_modules\puppeteer\lib\helper.js:111:23)
at C:\MEAN\puppeteer-demo\index.js:7:20
at process._tickCallback (internal/process/next_tick.js:68:7)
感谢任何帮助。我也愿意接受任何其他可能的解决方案。
【问题讨论】:
您将无法从 PDF 中截取屏幕截图,因为 Chromium 没有创建目标。当 Chromium 加载一个 PDf 时,它正在加载一个 PDF 查看器,这不是目标开发人员工具可以调试的。 【参考方案1】:对于现在遇到这个问题的任何人,我通过使用 Puppeteer、EJS 和 PDF.js 的组合来做到这一点,因为 puppeteer 本身不查看 PDF 文件。
我的方法基本上是使用 EJS 动态添加一个 URL,该 URL 将通过 PDF.js 查看,然后 puppeteer 将对其进行截图。
这里是 JS 部分
const ejs = require('ejs');
const puppeteer = require('puppeteer');
(async () =>
const browser = await puppeteer.launch(
args: [
'--disable-web-security',
'--disable-features=IsolateOrigins',
'--disable-site-isolation-trials'
]
);
const page = await browser.newPage();
const url = "https://example.com/test.pdf";
const html = await ejs.renderFile('./template.ejs', data: url );
await page.setContent(html);
await page.waitForNetworkIdle();
const image = await page.screenshot( encoding: 'base64' );
await browser.close();
console.log('Image: ', image);
)();
我在 puppeteer 启动中添加了 chromium args,以允许按照 this answer 不加载 pdf 文件。
这是 EJS 模板
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body
width: 100vw;
height: 100vh;
margin: 0;
#page
display: flex;
width: 100%;
height: 100%;
</style>
<title>Document</title>
</head>
<body>
<canvas id="page"></canvas>
<script src="https://unpkg.com/pdfjs-dist@2.0.489/build/pdf.min.js"></script>
<script>
(async () =>
const pdf = await pdfjsLib.getDocument('<%= data.url %>');
const page = await pdf.getPage(1);
const viewport = page.getViewport(1);
const canvas = document.getElementById('page');
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext =
canvasContext: context,
viewport: viewport
;
page.render(renderContext);
)();
</script>
</body>
</html>
请注意,此代码只会截取第一页的屏幕截图。
【讨论】:
【参考方案2】:Chromium 不允许在 headless true 模式下打开 pdf 文件,请改用 headless false 模式。 await puppeteer.launch(args: ['--no-sandbox'], headless: false )
【讨论】:
【参考方案3】:Headless Chrome 是 not able to visit PDF pages,并且会在您遇到时抛出错误 Error: net::ERR_ABORTED
。虽然您可以使用headless: false
访问 PDF 文档,但截屏也会失败,因为 PDF 不是真正的网站,实际上是在单独的视图中呈现的。
替代方法
您可以做的是下载页面并使用PDF.js 创建页面的图像。您可能想查看有关“pdf 到图像”或“pdf 预览”主题的其他信息。关于该主题以及 examples on the PDF.js page 本身的 *** 有多个问题(1、2、..)。
【讨论】:
谢谢,我正在寻找一种下载 pdf 的方法,但这可能会为我节省很多时间。 你也可以只使用 PDF.js 来完成所有工作,这样你仍然可以在无头模式下做 puppeteer 的事情。您可以在同一脚本中同时使用 puppeteer 和 PDF.js。在选择使用哪一个之前,您可以/\.pdf$/.test( url )
。我对 PDF.js 的探索还不足以了解它在下载和图像方面的所有功能,所以我不会谈论这个,但我已经能够结合使用它们来完成我自己的工作.以上是关于如何使用 puppeteer 和 Node js 为 pdf 页面生成屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章
使用Puppeteer将Node悬停在Node.js中的element和getComputedStyle上?
如何在 puppeteer Node.js 中将 const 添加到 await page.$eval?
使用 Puppeteer 和 Node.JS 在网站上的 iFrame 中找不到隐藏的输入元素
Node Js & Puppeteer - 如何选择包裹在 Anchor 标签内的文本
如何在 puppeteer Node.js 中将 const 添加到 await page.$x? xpath 中的常量