web-dev-qa-db-de.com

Puppenspieler warten, bis alle Bilder geladen sind, und machen dann einen Screenshot

Ich verwende Puppeteer , um zu versuchen, einen Screenshot einer Website zu erstellen, nachdem alle Bilder geladen wurden, aber nicht funktionieren.

Hier ist der Code, den ich bis jetzt habe, ich benutze https://www.digg.com als Beispielwebsite:

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://www.digg.com/');

    await page.setViewport({width: 1640, height: 800});

    await page.evaluate(() => {
        return Promise.resolve(window.scrollTo(0,document.body.scrollHeight));
    });

    await page.waitFor(1000);

    await page.evaluate(() => {
        var images = document.querySelectorAll('img');

        function preLoad() {

            var promises = [];

            function loadImage(img) {
                return new Promise(function(resolve,reject) {
                    if (img.complete) {
                        resolve(img)
                    }
                    img.onload = function() {
                        resolve(img);
                    };
                    img.onerror = function(e) {
                        resolve(img);
                    };
                })
            }

            for (var i = 0; i < images.length; i++)
            {
                promises.Push(loadImage(images[i]));
            }

            return Promise.all(promises);
        }

        return preLoad();
    });

    await page.screenshot({path: 'digg.png', fullPage: true});

    browser.close();
})();
15
Petar Vasilev

Es gibt eine eingebaute Option dafür: 

await page.goto('https://www.digg.com/', {"waitUntil" : "networkidle0"});

networkidle0 - Betrachten Sie die Navigation als abgeschlossen, wenn für mindestens 500 ms nicht mehr als 0 Netzwerkverbindungen bestehen

networkidle2 - Die Navigation sollte abgeschlossen sein, wenn für mindestens 500 ms nicht mehr als 2 Netzwerkverbindungen bestehen.

P.S. Natürlich funktioniert das nicht, wenn Sie mit endlosen Einzelbild-Anwendungen wie Twitter arbeiten.

42
Vaviloff

Eine weitere Option ist die Auswertung, um einen Rückruf zu erhalten, wenn alle Bilder geladen wurden

Diese Option funktioniert auch mit setContent , das die wait networkidle0-Option nicht unterstützt

await page.evaluate(async () => {
  const selectors = Array.from(document.querySelectorAll("img"));
  await Promise.all(selectors.map(img => {
    if (img.complete) return;
    return new Promise((resolve, reject) => {
      img.addEventListener('load', resolve);
      img.addEventListener('error', reject);
    });
  }));
})
8
Daniel Krom

Ich habe genau das gleiche Problem ... Ich habe das Gefühl, dass die Lösung die Verwendung von

await page.setRequestInterceptionEnabled(true);

page.on('request', interceptedRequest => {
    //some code here that adds this request to ...
    //a list and checks whether all list items have ...
    //been successfully completed!
});

https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagesetrequestinterceptionenabledvalue

0
Wissa