【问题标题】:How to get Document.readyState in puppeteer / headless Chrome?如何在 puppeteer / headless Chrome 中获取 Document.readyState?
【发布时间】:2018-09-07 11:16:29
【问题描述】:

使用 puppeteer,我无法弄清楚如何获取 document.readyState。我需要等到页面加载完毕后再渲染 pdf。

    const browser = await puppeteer.launch({
        headless: true,
        args: ['--no-sandbox']
    });
    const page = await browser.newPage();

    console.log('Setting HTML content...');

    // Can't POST data with headless chrome, so we have to get the HTML and set the content of the page, then render that to a PDF
    await page.setContent(html);

    // Generates a PDF with 'screen' media type.
    await page.emulateMedia('screen');

    var renderPage = function () {
        return new Promise(async resolve => {

            await page.evaluate((document) => {
                console.log(document);
                const handleDocumentLoaded =  () => {
                    console.log('readyState: ', document.readyState);
                    console.log('Rendering PDF...');
                    Promise.resolve(resolve(page.pdf({ path: thisPDFfileName, format: 'Letter' })));
                };
                if (document.readyState === "loading") {
                    document.addEventListener("DOMContentLoaded", handleDocumentLoaded);
                } else {
                    handleDocumentLoaded();
                }
            });

            // I also tried this... no luck
            // setTimeout(async function () {
            //     console.log('Awaiting document...');
            //
            // const handle = await page.evaluateHandle(() => ({window, document}));
            // const properties = await handle.getProperties();
            // const windowHandle = properties.get('window');
            // const documentHandle = properties.get('document');
            // await handle.dispose();
            //
            //     console.log('readyState: ', documentHandle.readyState);
            //     if ("complete" === documentHandle.readyState) {
            //         await documentHandle.dispose();
            //         console.log('readyState: ', doc.readyState);
            //         console.log('Rendering PDF...');
            //         resolve(page.pdf({ path: thisPDFfileName, format: 'Letter' }));
            //     } else {
            //         renderPage();
            //     }
            // }), 250;
        });
    };
    // Delay required to allow page to render JS before creating PDF
    await renderPage();
    await browser.close();
    sendPdfToClient();

我尝试了evaluateHandle 并且只能获取innerHTML,而不是文档对象本身。

获取包含readyStatedocument 对象的正确方法是什么?

最后,我应该为loadedDOMContentLoaded设置一个监听器,我需要等到google maps JS渲染地图?如果需要,我可以发送自定义事件,因为我控制正在呈现的页面。

【问题讨论】:

    标签: node.js async-await pdf-generation puppeteer google-chrome-headless


    【解决方案1】:

    如果您使用page.goto(),则可以使用waitUntil 选项指定何时将导航视为完成:

    waitUntil 事件包括:

    • load - 考虑在加载事件触发时完成导航。
    • domcontentloaded - 考虑在DOMContentLoaded 事件触发时完成导航。
    • networkidle0 - 至少在500 ms 内没有超过 0 个网络连接时,考虑完成导航。
    • networkidle2 - 在至少500 毫秒内没有超过 2 个网络连接时,认为导航完成。

    或者,您可以使用page.on() 等待'domcontentloaded' 事件或'load' 事件。

    【讨论】:

      【解决方案2】:

      我想我过于复杂了。好像已经有了

      page.once('load', () => console.log('Page loaded!'));
      

      正是这样做的。 :-D

      在此处查看详细文档:

      https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#event-load

      有 2 个事件与您的问题相关

      1. event: 'domcontentloaded'
      2. event 'load'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-05
        • 2019-03-17
        • 2018-08-07
        • 2020-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多