Как получить Document.readyState в кукольном / безголовом Chrome?

Используя кукольник, я не могу понять, как получить 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, содержащий readyState?

Наконец, следует ли установить прослушиватель для loaded или DOMContentLoaded, мне нужно дождаться, пока Google Maps JS отобразит карту? При необходимости я могу отправить настраиваемое событие, так как я контролирую отображение страницы.


person TetraDev    schedule 05.01.2018    source источник


Ответы (2)


Если вы используете page.goto(), вы можете используйте параметр waitUntil, чтобы указать, когда считать навигацию завершенной:

waitUntil события включают:

  • load - считайте, что навигация завершена, когда срабатывает событие загрузки.
  • domcontentloaded - считайте, что навигация завершена при возникновении события DOMContentLoaded.
  • networkidle0 - считайте, что навигация завершена, если не более 0 сетевых подключений в течение как минимум 500 мс.
  • networkidle2 - считайте, что навигация завершена, если не более 2 сетевых подключений в течение как минимум 500 мс.

Кроме того, вы можете использовать page.on(), чтобы дождаться 'domcontentloaded' или 'load'.

person Grant Miller    schedule 07.09.2018

Думаю, я слишком усложнил это. Видимо уже есть

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'
person TetraDev    schedule 05.01.2018