如何在puppeteer / headless Chrome中获取Document.readyState?

时间:2018-01-05 18:58:27

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

使用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,而不是文档对象本身。

获取包含document的{​​{1}}对象的正确方法是什么?

最后,如果我为readyStateloaded设置了一个监听器,我需要等到谷歌地图JS呈现地图吗?如果需要,我可以发送自定义事件,因为我控制正在呈现的页面。

2 个答案:

答案 0 :(得分:0)

我想我过于复杂了。显然已经有了

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

正是如此。 :-D

请参阅此处的详细文档:

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

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

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

答案 1 :(得分:0)

如果您使用的是this issue,则可以使用waitUntil选项指定何时将导航视为完成:

waitUntil事件包括:

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

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