我写了一个脚本来拍摄网页上50个尺寸图表的屏幕截图。每个图表都包含在一个元素中。有趣的是,仅捕获了前三个表格图表,其余的PNG文件为空白,完全为白色。
由于图表是从数据库中提取的,所以我认为可能是在截屏之前尚未完成页面的加载,因此我添加了{“ waitUntil”:“ networkidle0”},但这并没有解决任何问题。尽管如此,该脚本仅创建前三个图表的屏幕截图,分别为0.png,1.png和2.png。其余的PNG文件3.png-49.png均已创建,但只有白色数据。
可能是什么问题?如果我在浏览器上访问该页面,则所有50个图表均完美加载,那么为什么Puppeteer仅截取前三个屏幕截图?这是我的脚本:
const puppeteer = require( 'puppeteer' );
( async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto( 'http://www.example.com/size-charts.php', { "waitUntil": "networkidle0" } );
// Get a list of all elements.
const elements = await page.$$( 'div.chartContainer' );
for( let i = 0; i < elements.length; i++ ) {
try {
// get screenshot of a particular element
await elements[ i ].screenshot( { path: `${ i }.png` } );
}
catch( e ) {
console.log( `Couldn't take a screenshot of the element with the index of: ${ i }. Reason: `, e );
}
}
await browser.close();
} )();
答案 0 :(得分:0)
虽然实际解决方案可以/应该等待每个元素可见,但是还有其他可能的解决方案。
您可以滚动到该元素,等待一段时间以正确呈现,然后截取屏幕截图。
elementHandle.screenshot()
滚动到该元素,但是没有办法延迟或等待该元素可见。
quick search on official repo显示,在此次活动中至少有19个未解决的问题提到blank screenshot
。
相反,在截屏之前,我们可以使用自定义.evaluate或.hover等滚动到元素。
elementHandle.hover()
:此方法在需要时将元素滚动到视图中,然后使用page.mouse将鼠标悬停在元素的中心。如果该元素与DOM分离,则该方法将引发错误。
让我们使用它,
// Get a list of all elements.
const elements = await page.$$('div.chartContainer');
for (let i = 0; i < elements.length; i++) {
// scrolls into view and hovers the element
await elements[i].hover();
// wait for some random number
await page.waitFor(1000);
// get screenshot of a particular element
await elements[i].screenshot({
path: `${ i }.png`
});
}
有人报告说,使用elementHandle.boundingBox()
解决了他们的问题。它的作用是,获取元素的位置,高度,宽度等,并将其用于屏幕截图。
// Get a list of all elements.
const elements = await page.$$('div.chartContainer');
for (let i = 0; i < elements.length; i++) {
// get screenshot of a particular area
await page.screenshot({ // <-- use page here
path: `${ i }.png`,
clip: await elements[i].boundingBox() // <-- use clip here
});
}
答案 1 :(得分:0)
我将回答自己的问题,希望它可以帮助其他人。在我的特定情况下,解决方案是将视口高度设置为非常大的数字,例如:
page.setViewport( { width: 1920, height: 100000 } );
此后,该脚本能够创建所有选定元素的屏幕截图。