无法使用 puppeteer 截取屏幕截图,它会转储一个空图像文件
Cannot take a screenshot using puppeteer, it dumps an empty image file
我有一个名为 test.html
的框架 html 文件,这是它包含的内容:
<!doctype html>
<html>
<head>
</head>
<body>
</body>
</html>
然后我还有一个文件,目的是chrome无头打开上面的文件,加一张图片进去然后截图,看看:
const puppeteer = require('puppeteer')
const fs = require('fs');
(async() => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('file://test.html')
await page.$eval('body', (body) => {
const imgElement = new window.Image()
imgElement.src = 'https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png'
body.appendChild(imgElement)
})
await page.waitForSelector('img')
fs.writeFileSync('output.html', await page.content())
await page.screenshot({
path: 'screenshot.jpg'
})
await browser.close()
})()
根据 运行 这段代码,我得到一个空的图像文件作为屏幕截图。您还可以注意到,我使用以下方式转储页面内容:
fs.writeFileSync('output.html', await page.content())
在我的浏览器中打开 output.html
包含我在屏幕截图中期望的图像。为什么生成的截图是空的?
这是因为您没有等待图片下载。您只在等待 await page.waitForSelector('img')
,但这个等待的是 DOM 元素,而不是实际图像。这是图像下载和截图之间的竞争条件。
您应该像这样等待图像 onload
:
await page.$eval('body', async (body) => {
const imgElement = new window.Image()
imgElement.src = 'https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png'
body.appendChild(imgElement)
await new Promise(resolve => {
imgElement.onload = resolve;
});
});
我有一个名为 test.html
的框架 html 文件,这是它包含的内容:
<!doctype html>
<html>
<head>
</head>
<body>
</body>
</html>
然后我还有一个文件,目的是chrome无头打开上面的文件,加一张图片进去然后截图,看看:
const puppeteer = require('puppeteer')
const fs = require('fs');
(async() => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('file://test.html')
await page.$eval('body', (body) => {
const imgElement = new window.Image()
imgElement.src = 'https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png'
body.appendChild(imgElement)
})
await page.waitForSelector('img')
fs.writeFileSync('output.html', await page.content())
await page.screenshot({
path: 'screenshot.jpg'
})
await browser.close()
})()
根据 运行 这段代码,我得到一个空的图像文件作为屏幕截图。您还可以注意到,我使用以下方式转储页面内容:
fs.writeFileSync('output.html', await page.content())
在我的浏览器中打开 output.html
包含我在屏幕截图中期望的图像。为什么生成的截图是空的?
这是因为您没有等待图片下载。您只在等待 await page.waitForSelector('img')
,但这个等待的是 DOM 元素,而不是实际图像。这是图像下载和截图之间的竞争条件。
您应该像这样等待图像 onload
:
await page.$eval('body', async (body) => {
const imgElement = new window.Image()
imgElement.src = 'https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png'
body.appendChild(imgElement)
await new Promise(resolve => {
imgElement.onload = resolve;
});
});