Puppeteer 在加载所有 iframe 之前创建 PDF
Puppeteer creates PDF before all iframes have loaded
我需要为包含大约 20 个显示一些图表的 iframe 的网页创建 PDF。显然,我需要等到所有 iframe 都加载完毕。为此,我尝试了以下(片段):
const browser = await puppeteer.launch({ args: ['--no-sandbox'] })
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation({waitUntil: 'networkidle0'})
await page.goto(url)
await navigationPromise
const pdf = await page.pdf()
await browser.close()
我的理解是 waitUntil: 'networkidle0'
选项应该等待 500 毫秒,直到完全没有网络流量。但是,iframe 并不总是显示,有些显示,有些不显示。
我也试过 networkidle2
但没有改善(这应该适用于长期 运行 网络连接,但我们的情况并非如此)。
还有什么其他方法可以确保所有 iframe 都已加载?
一般来说,load
和 networkidle*
事件应该在帧加载后触发。但是,如果框架在 page.waitForNavigation
解决后附加到页面,您可能需要专门监听要加载的框架。
有framenavigated
事件,即"emitted when a frame is navigated to a new url"。如果您知道需要收听的帧数,您可以像这样等到所有帧都加载完毕:
const EXPECTED_NUMBER_OF_FRAMES = 5;
await Promise.all([
new Promise(resolve => { // wait until all frames are navigated
let numberOfLoadedFrames = 0;
page.on('framenavigated', () => {
numberOfLoadedFrames += 1;
if (numberOfLoadedFrames === (EXPECTED_NUMBER_OF_FRAMES + 1)) {
resolve();
}
});
}),
page.goto('...')
]);
代码将监听 framenavigated
事件调用的数量,并在达到预期数量时监听 resolve
Promise。请记住,主框架也会触发一次 framenavigated
事件,因此我的代码中的 EXPECTED_NUMBER_OF_FRAMES + 1
。
根据页面的复杂程度,您还可以监听发出的 frameattached
事件数,这将表明页面中有多少帧。这样您就可以自动检测页面中有多少帧。但是,在这种情况下,您应该先等待几毫秒,以确保捕捉到所有帧。
我需要为包含大约 20 个显示一些图表的 iframe 的网页创建 PDF。显然,我需要等到所有 iframe 都加载完毕。为此,我尝试了以下(片段):
const browser = await puppeteer.launch({ args: ['--no-sandbox'] })
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation({waitUntil: 'networkidle0'})
await page.goto(url)
await navigationPromise
const pdf = await page.pdf()
await browser.close()
我的理解是 waitUntil: 'networkidle0'
选项应该等待 500 毫秒,直到完全没有网络流量。但是,iframe 并不总是显示,有些显示,有些不显示。
我也试过 networkidle2
但没有改善(这应该适用于长期 运行 网络连接,但我们的情况并非如此)。
还有什么其他方法可以确保所有 iframe 都已加载?
一般来说,load
和 networkidle*
事件应该在帧加载后触发。但是,如果框架在 page.waitForNavigation
解决后附加到页面,您可能需要专门监听要加载的框架。
有framenavigated
事件,即"emitted when a frame is navigated to a new url"。如果您知道需要收听的帧数,您可以像这样等到所有帧都加载完毕:
const EXPECTED_NUMBER_OF_FRAMES = 5;
await Promise.all([
new Promise(resolve => { // wait until all frames are navigated
let numberOfLoadedFrames = 0;
page.on('framenavigated', () => {
numberOfLoadedFrames += 1;
if (numberOfLoadedFrames === (EXPECTED_NUMBER_OF_FRAMES + 1)) {
resolve();
}
});
}),
page.goto('...')
]);
代码将监听 framenavigated
事件调用的数量,并在达到预期数量时监听 resolve
Promise。请记住,主框架也会触发一次 framenavigated
事件,因此我的代码中的 EXPECTED_NUMBER_OF_FRAMES + 1
。
根据页面的复杂程度,您还可以监听发出的 frameattached
事件数,这将表明页面中有多少帧。这样您就可以自动检测页面中有多少帧。但是,在这种情况下,您应该先等待几毫秒,以确保捕捉到所有帧。