如何在 puppeteer 中滚动浏览多个 iframe
how to scroll through multiple iframes in puppeteer
我正在尝试使用 puppeteer 生成包含多个 iframe 的 pdf。我遇到的一个问题是,如果我嵌入类似 google 地图的东西,google 地图将延迟加载(它仅在元素位于浏览器的视角时加载。
一种解决方案是在页面上滚动浏览不同的 iframe,并为每个 iframe 设置加载等待时间。
这是我目前所拥有的(能够在 https://try-puppeteer.appspot.com/ 中测试)木偶操纵者:版本 1.9.0,我也在 1.12.0 中尝试过,无法使滚动工作或超时。
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 750
});
await page.emulateMedia('screen');
const html = '<iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe><div><iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe></div><div><iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe></div><div><iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe></div>'
await page.setContent(html, { waitUntil: 'networkidle0' });
const frames = await page.mainFrame().childFrames(); // get all the iframes on that page.
await page.evaluate((frames) => {
// this part does not work
for (let i=0, i<frames.length; i++){
setTimeout(() => {
document.querySelectorAll('iframe')[i].scrollIntoView();
}, 2000)
}
}, frames)
const pdf = await page.pdf({
scale: 1,
printBackground: true,
margin: { bottom: 0 },
path: 'screenshot.pdf'
});
await browser.close();
感谢任何帮助!
这段代码有一些问题:
frames
是来自 Node.js 上下文的不可序列化对象,因此它不能按原样在浏览器上下文中传输。
- 所有
setTimeout()
回调将在 2 秒后立即调用,因此每一帧都没有足够的时间加载。
- 不等待这些
setTimeout()
回调:page.evaluate()
returns 在 iframe 加载之前的 2 秒传递和 pdf 创建之前。
你可以试试这个方法:
// page loaded
await page.evaluate(async () => {
for (const iframe of Array.from(document.querySelectorAll('iframe'))) {
iframe.scrollIntoView();
await new Promise((resolve) => { setTimeout(resolve, 2000); });
}
});
// pdf creation
我正在尝试使用 puppeteer 生成包含多个 iframe 的 pdf。我遇到的一个问题是,如果我嵌入类似 google 地图的东西,google 地图将延迟加载(它仅在元素位于浏览器的视角时加载。 一种解决方案是在页面上滚动浏览不同的 iframe,并为每个 iframe 设置加载等待时间。
这是我目前所拥有的(能够在 https://try-puppeteer.appspot.com/ 中测试)木偶操纵者:版本 1.9.0,我也在 1.12.0 中尝试过,无法使滚动工作或超时。
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 750
});
await page.emulateMedia('screen');
const html = '<iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe><div><iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe></div><div><iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe></div><div><iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12077.188806999058!2d-73.2243774!3d40.8214352!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x9e562057f79c0860!2sH+Lee+Dennison+Building!5e0!3m2!1sen!2sus!4v1547750310674" height="250" width="600" allowfullscreen=""></iframe></div>'
await page.setContent(html, { waitUntil: 'networkidle0' });
const frames = await page.mainFrame().childFrames(); // get all the iframes on that page.
await page.evaluate((frames) => {
// this part does not work
for (let i=0, i<frames.length; i++){
setTimeout(() => {
document.querySelectorAll('iframe')[i].scrollIntoView();
}, 2000)
}
}, frames)
const pdf = await page.pdf({
scale: 1,
printBackground: true,
margin: { bottom: 0 },
path: 'screenshot.pdf'
});
await browser.close();
感谢任何帮助!
这段代码有一些问题:
frames
是来自 Node.js 上下文的不可序列化对象,因此它不能按原样在浏览器上下文中传输。- 所有
setTimeout()
回调将在 2 秒后立即调用,因此每一帧都没有足够的时间加载。 - 不等待这些
setTimeout()
回调:page.evaluate()
returns 在 iframe 加载之前的 2 秒传递和 pdf 创建之前。
你可以试试这个方法:
// page loaded
await page.evaluate(async () => {
for (const iframe of Array.from(document.querySelectorAll('iframe'))) {
iframe.scrollIntoView();
await new Promise((resolve) => { setTimeout(resolve, 2000); });
}
});
// pdf creation