【问题标题】:Take screenshots of different elements with specific names in Puppeteer在 Puppeteer 中截取具有特定名称的不同元素的屏幕截图
【发布时间】:2021-08-26 23:42:46
【问题描述】:

我正在尝试对可能包含多个部分的登录页面中的每个部分进行截图。我能够在我注释掉的“Round1”中有效地做到这一点。

我的目标是学习如何编写更精简/更简洁的代码,所以我又做了一次尝试,“Round2”。

在本节中,它会截取屏幕截图。但是,它使用文件名JSHandle@node.png 截取第 3 节的屏幕截图。当然,我做错了。

Round1(完美运行)

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

// const elOne = await page.$('.section-one');
// await elOne.screenshot({path: './public/SectionOne.png'}) 
// takes a screenshot SectionOne.png

// const elTwo = await page.$('.section-two')
// await elTwo.screenshot({path: './public/SectionTwo.png'})
// takes a screenshot SectionTwo.png

// const elThree = await page.$('.section-three')
// await elThree.screenshot({path: './public/SectionThree.png'})
// takes a screenshot SectionThree.png

第二轮

我创建了一个包含所有变量的数组并尝试遍历它们。

const elOne = await page.$('.section-one');
const elTwo = await page.$('.section-two')
const elThree = await page.$('.section-three')
    
    let lpElements = [elOne, elTwo, elThree];
        for(var i=0; i<lpElements.length; i++){

            await lpElements[i].screenshot({path: './public/'+lpElements[i] + '.png'})       
    }
await browser.close();
})();

这仅截取第三部分的屏幕截图,但文件名错误 (JSHandle@node.png)。控制台上没有错误消息。 如何通过修改 Round2 代码重现 Round1?

【问题讨论】:

  • 傀儡师不是傀儡。标签已编辑。

标签: javascript arrays puppeteer


【解决方案1】:

您的数组仅包含正在调用 .toString() 的 Puppeteer 元素句柄对象。

一个干净的方法是使用一个对象数组,每个对象都有一个选择器及其名称。然后,当您运行循环时,您可以访问名称和选择器。

const puppeteer = require('puppeteer');

const content = `
  <div class="section-one">foo</div>
  <div class="section-two">bar</div>
  <div class="section-three">baz</div>
`;
const elementsToScreenshot = [
  {selector: '.section-one', name: 'SectionOne'},
  {selector: '.section-two', name: 'SectionTwo'},
  {selector: '.section-three', name: 'SectionThree'},
];
const getPath = name => `./public/${name}.png`;

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.setContent(content);

  for (const {selector, name} of elementsToScreenshot) {
    const el = await page.$(selector);
    await el.screenshot({path: getPath(name)});
  }
})()
  .catch(err => console.error(err))
  .finally(async () => await browser.close())
;

【讨论】:

  • 我看到了创建 Obj 和使用键的逻辑,并将它们传递给 for 循环。这看起来很棒,我一定要试试这个。但我有两个问题。为什么“浏览器”定义在异步函数外部而不是内部?创建变量 const [pages] 到 const page 有什么意义?我仍然在学习。非常感谢!!!
  • 很高兴它对您有所帮助。在 IIFE 之外定义browser 启用.finally(async () =&gt; await browser.close()),这是一种关闭浏览器的干净方法,无论是否发生错误。 const [page] = await browser.pages() 使用数组解构来选择第一页——浏览器从一页开始,因此不需要newPage()。与const page = (await browser.pages())[0]; 相同。 This post 解释了我的 Puppeteer 设置的这些细节。
  • 很有道理!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
相关资源
最近更新 更多