私は Puppeteer を使用して、すべての画像が読み込まれたが機能しなかった後にWebサイトのスクリーンショットを撮ろうとしました。
ここに私がこれまでに手に入れたコードがあります。私は https://www.digg.com をサンプルWebサイトとして使用しています。
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();
})();
そのための 組み込みオプション があります。
await page.goto('https://www.digg.com/', {"waitUntil" : "networkidle0"});
networkidle0-少なくとも500ミリ秒間ネットワーク接続が0を超えていない場合、ナビゲーションが終了したと見なします
networkidle2-少なくとも500 msの間、ネットワーク接続が2つ以下の場合にナビゲーションが終了したと見なします。
追伸もちろん、Twitterのような無限スクロール、単一ページのアプリケーションで作業している場合は機能しません。
別のオプション、すべての画像がロードされたときに実際にコールバックを取得するために評価する
このオプションは、wait networkidle0
オプションをサポートしない setContent でも機能します。
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);
});
}));
})
私はまったく同じ問題に直面しています。私は解決策が使用することを伴うと感じています:
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!
});