简体   繁体   English

puppeteer 一一截图元素孩子

[英]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.

相关问题 使用 puppeteer 截屏并将其存储在谷歌云存储中 - Taking a screenshot with puppeteer and storing it in google cloud storage JQuery:排除孩子的一个元素 - JQuery: exclude one element of the children 为什么 puppeteer 不截图整个元素? - Why puppeteer doesnt screenshot the whole element? 在 Puppeteer 中设置元素截图的宽度和高度 - Set Width and Height of Element Screenshot in Puppeteer 在Puppeteer中截取屏幕截图或PDF之前,如何删除标签? - How Can I Remove Tag before taking a Screenshot or PDF in Puppeteer? 在使用 puppeteer 截屏之前在页面上查找特定的 div 并删除 - Find specific divs on page and remove before taking screenshot with puppeteer 只获取数组及其子元素的一个元素 - Getting only one element of the array and its children 如何在一行中选择此元素和下一个元素的子代? - How to select this element and children of next element in one line? 在One Plus 7 Pro中截图时崩溃的android应用[React-Native] - Crashing android app while taking screenshot in One Plus 7 Pro [React-Native] 是否可以在创建屏幕截图之前使用 Puppeteer 修改 DOM 中的元素? - Is it possible to modify an element in the DOM with Puppeteer before creating a screenshot?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM