Javascript 如何在Puppeter中滚动多个iFrame

Javascript 如何在Puppeter中滚动多个iFrame,javascript,node.js,iframe,web-scraping,puppeteer,Javascript,Node.js,Iframe,Web Scraping,Puppeteer,我正在尝试使用Puppeter生成带有多个iFrame的pdf。我遇到的一个问题是,如果我嵌入像谷歌地图这样的东西,谷歌地图将延迟加载(它只在元素位于浏览器的视图中时加载)。 一种解决方案是滚动页面上的不同iframe,并设置每个iframe加载的等待时间 以下是我到目前为止(能够在)Puppeter中测试的:版本1.9.0,我也在1.12.0中尝试过,无法使滚动正常工作,也无法超时 const browser = await puppeteer.launch(); const page = a

我正在尝试使用Puppeter生成带有多个iFrame的pdf。我遇到的一个问题是,如果我嵌入像谷歌地图这样的东西,谷歌地图将延迟加载(它只在元素位于浏览器的视图中时加载)。 一种解决方案是滚动页面上的不同iframe,并设置每个iframe加载的等待时间

以下是我到目前为止(能够在)Puppeter中测试的:版本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();
const browser=wait puppeter.launch();
const page=wait browser.newPage();
等待page.setViewport({
宽度:1280,
身高:750
});
等待页面。仿真媒体(“屏幕”);
常量html=''
wait page.setContent(html,{waitUntil:'networkidle0'});
const frames=wait page.mainFrame().childFrames();//获取该页面上的所有iframe。
等待页面。评估((帧)=>{
//这部分不起作用
对于(设i=0,i{
document.querySelectorAll('iframe')[i].scrollIntoView();
}, 2000)
}
},框架)
const pdf=wait page.pdf({
比例:1,
背景:是的,
边距:{底部:0},
路径:'screenshot.pdf'
});
等待浏览器关闭();

非常感谢您的帮助!

此代码有一些问题:

  • frames
    是Node.js上下文中的不可序列化对象,因此无法在浏览器上下文中按原样传输
  • 所有
    setTimeout()
    回调将在2秒后立即调用,因此每个帧都没有足够的时间加载
  • 不等待这些
    setTimeout()
    回调:
    page.evaluate()
    在这2秒传递之前返回,并且在iframe加载之前创建pdf
  • 您可以尝试以下方法:

    //已加载页面
    等待页面。评估(异步()=>{
    for(数组的常量iframe.from(document.querySelectorAll('iframe')){
    iframe.scrollIntoView();
    等待新的承诺((resolve)=>{setTimeout(resolve,2000);});
    }
    });
    //pdf创建
    
    我确实有一个编译错误,不确定您是否知道解决方案
    类型“NodeListOf”必须有一个“[Symbol.iterator]”()'返回迭代器的方法。
    这很奇怪。对于
    NodeList
    没有迭代器接口的浏览器/浏览器版本,是否采用此代码?如果是,请尝试新版本:我已将
    document.querySelectorAll('iframe')
    包装在
    Array.from()中。