我正在尝试获取带有puppeteer的网页的屏幕截图,我想通过使用以下类型的数据依次逐个显示来逐个截图每个元素: / p>
p (visibility:hidden)
ol
li (visibility:hidden)
li (visibility:hidden)
在这种情况下,我将p更改为visible,进行屏幕截图,进入ol,将li设置为visible,进行屏幕截图,等等。
我几乎可以使用以下功能:
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),}})
}
在 await page.evaluate 中,我无法调用 div.screenshot ,出现以下错误:
(node:26413) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: div.screenshot is not a function
我确实尝试过 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
在 page.evaluate 之后,我可以,但是在那种情况下,我错过了每个li的“揭幕”。
在这种情况下,我绝对不知道我在处理等待和异步操作...
我不明白如何将匿名函数转换为异步函数以适合页面内部。
如何在page.evaluate中调用div.screenshot?
谢谢
答案 0 :(得分:0)
实际上,您对page.evaluate
感到困惑。 page.evaluate
方法是伪造函数,用于在Chromium伪造者的浏览器中运行脚本,而不是在伪造者自身中运行脚本。两者都是不同的上下文,并且具有自己的环境,并且您不能共享变量或常量。
您不能在page.evaluate
内调用div.screenshot
我尝试制作一些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>
然后你去。
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 })
}
}
})()