[英]puppeteer taking screenshot of element children one by one
I'm trying to get a screenshot of a webpage with puppeteer, I want to take a screenshot of each elements one by one by revealing them 1 after another with the following type of data:我正在尝试使用 puppeteer 获取网页的屏幕截图,我想通过使用以下类型的数据一个接一个地显示每个元素来一个一个地截取每个元素的屏幕截图:
p (visibility:hidden)
ol
li (visibility:hidden)
li (visibility:hidden)
In that case, I'll change p to visible, take a screenshot, go in the ol, set li to visible, take a screenshot, and so on.在这种情况下,我会将 p 更改为可见,截取屏幕截图,进入 ol,将 li 设置为可见,截取屏幕截图等等。
I'm almost able to make it work with the following function :我几乎可以使用以下功能使其工作:
const browser = await puppeteer.launch({args: ['--window-size=1920,1080','--no-sandbox', '--disable-setuid-sandbox']});
const page = await browser.newPage();
await page.goto('http://mywebsite',{waitUntil: 'networkidle2'});
const div = await page.$("[id^=t1_]");
const bbox = await div.boundingBox();
let nbElem=await page.evaluate(() => {
return document.querySelector('[class$=-root]').childElementCount
});
for(let i=1;i<=nbElem;i++){
await page.evaluate((i) => {
let elem = document.querySelector('[class$=-root] > *:nth-child('+i+')')
if(elem.tagName==="P"){
elem.style.visibility = 'visible';
div.screenshot({path: "test"+i+"0.png",clip: {x: bbox.x,y:bbox.y,width: bbox.width,height: bbox.height}})
}else{
let j=0;
let children = elem.children;
for(let z of children){
z.style.visibility='visible';
div.screenshot({path: "test"+i+(j++)+".png",clip: {x: bbox.x,y:bbox.y,width: bbox.width,height: bbox.height}})
}
}
},i);
// await div.screenshot({path: "test"+i+(j++)+".png",clip: {x: bbox.x,y:bbox.y,width: Math.min(bbox.width, page.viewport().width),height: Math.min(bbox.height, page.viewport().height),}})
}
Once in the await page.evaluate , I can't call div.screenshot , I get the following error : (node:26413) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: div.screenshot is not a function
一旦进入await page.evaluate ,我就无法调用div.screenshot ,我收到以下错误:
(node:26413) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: div.screenshot is not a function
I did try to call it with the await , but get another error :我确实尝试用await调用它,但得到另一个错误:
await div.screenshot({path: "test"+i+"0.png",clip: {x: bbox.x,y:bbox.y,width: bbox.width,height: bbox.height}})
^^^^^
SyntaxError: await is only valid in async function
while after page.evaluate , I can, but in that case, I'm missing the "unveiling" of each li.在page.evaluate之后,我可以,但在那种情况下,我错过了每个 li 的“揭幕”。
I definitely don't know what I'm doing with the await and async stuff in that case ...在那种情况下,我绝对不知道我在用 await 和 async 做什么......
I don't understand how I could transform the anonymous function into a async one to fit inside the page.evaluate.我不明白如何将匿名函数转换为异步函数以适应 page.evaluate。
How should I call div.screenshot within page.evaluate ?我应该如何在 page.evaluate 中调用 div.screenshot ?
Thanks谢谢
Actually you were confused with the page.evaluate
really means.实际上,您对
page.evaluate
真正含义感到困惑。 The page.evaluate
method is the puppeteer function to run script INSIDE the Chromium puppeteer's browser, not in puppeteer itself. page.evaluate
方法是page.evaluate
函数,用于在 Chromium puppeteer 的浏览器中运行脚本,而不是在 puppeteer 本身中运行。 Both were different contexts and have it's own environment, and you can't share variables or constants.两者都是不同的上下文,都有自己的环境,您不能共享变量或常量。
And you can't call div.screenshot within page.evaluate
而且你不能在
page.evaluate
调用page.evaluate
I tried to make some HTML to reproduce your case, coba.html
:我尝试制作一些 HTML 来重现您的案例
coba.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body class="body-root">
<p style="visibility:hidden">Hallo</p>
<p style="visibility:hidden">World</p>
<p style="visibility:hidden">How Are You?</p>
<ol>
<li style="visibility:hidden">1</li>
<li style="visibility:hidden">3</li>
<li style="visibility:hidden">5</li>
<li style="visibility:hidden">7</li>
<li style="visibility:hidden">9</li>
<li style="visibility:hidden">A</li>
</ol>
<ol>
<li style="visibility:hidden">2</li>
<li style="visibility:hidden">4</li>
<li style="visibility:hidden">6</li>
<li style="visibility:hidden">8</li>
<li style="visibility:hidden">10</li>
<li style="visibility:hidden">B</li>
</ol>
</body>
</html>
And here you go.给你。
const puppeteer = require ('puppeteer')
;(async () => {
const browser = await puppeteer.launch({
headless: false,
devtools: true,
args: [
'--window-size=1920,1080',
'--no-sandbox',
'--disable-setuid-sandbox'
]
})
const [page] = await browser.pages ()
await page.goto('http://localhost/testing/coba.html',{ waitUntil: 'networkidle0' })
await page.evaluate ( () => {
document.querySelector('[class$="-root"]').childNodes.forEach( element => {
if (typeof (element.tagName) !== 'undefined'){
if (element.tagName === 'P') {
element.style.visibility = 'visible'
} else {
element.childNodes.forEach( elemChild => {
if (typeof (elemChild.tagName) !== 'undefined'){
elemChild.style.visibility = 'visible'
}
})
}
}
})
})
const pElements = await page.$$('[class$="-root"] > p')
for ( let num = 0; num < pElements.length; num++ ) {
var pElementBoundingBox = await pElements[num].boundingBox ()
pElements[num].screenshot ({ path: `p_elem_${num+1}.png`, clip: pElementBoundingBox })
}
const olElements = await page.$$('[class$="-root"] > ol')
for ( let numol = 0; numol < olElements.length; numol++ ) {
var liElements = await olElements[numol].$$('li')
for ( let numli = 0; numli < liElements.length; numli++ ) {
var liElementBoundingBox = await liElements[numli].boundingBox ()
liElements[numli].screenshot ({ path: `li_elem_${numol+1}_${numli+1}.png`, clip: liElementBoundingBox })
}
}
})()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.