返回

自动化测试实战:使用 Puppeteer 有效截图,克服多标签页困局

见解分享

在自动化测试和日常开发中,网页截图是一个非常有用的功能。Puppeteer 是一个非常流行的 Node.js 库,可以用来控制无头 Chrome 或 Chromium 浏览器。它提供了丰富的 API,可以用来执行各种操作,包括网页截图。

在 Puppeteer 中,我们可以使用 page.screenshot() 方法来对当前页面进行截图。这个方法可以接受一个可选的 options 对象,用于指定截图的各种选项,例如文件的保存路径、截图的尺寸和格式等。

在业务复杂且量大的情况下,一般都是几百个或者上千个页面需要处理。我们通常都是 Promise.all() 并行处理异步,进行批量截图,但标签页一多,就会导致机器性能急剧下降。

为了解决这个问题,我们可以把打开浏览器的个数和每个浏览器的标签页数都抽出来,可灵活调整,便于不同配置的机器在执行任务时,可以根据自身的情况进行调整。

const puppeteer = require('puppeteer');

(async () => {
  // 打开浏览器
  const browser = await puppeteer.launch();

  // 创建一个新的页面
  const page = await browser.newPage();

  // 设置页面大小
  await page.setViewport({ width: 1280, height: 800 });

  // 循环需要截图的页面
  for (let i = 0; i < 1000; i++) {
    // 打开页面
    await page.goto('https://example.com');

    // 截图
    await page.screenshot({ path: `screenshot-${i}.png` });
  }

  // 关闭浏览器
  await browser.close();
})();

这样,我们就可以根据不同的机器配置来调整打开浏览器的数量和每个浏览器的标签页数,从而优化截图性能。

除了上述方法,我们还可以使用 Puppeteer 的 cluster 模块来进一步优化性能。cluster 模块可以用来创建一个工作进程池,并行执行任务。这样,我们可以将截图任务分配给不同的工作进程,从而充分利用多核 CPU 的优势。

const puppeteer = require('puppeteer');
const cluster = require('cluster');

if (cluster.isMaster) {
  // 创建一个工作进程池
  const numCPUs = require('os').cpus().length;
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // 监听工作进程的退出事件
  cluster.on('exit', (worker) => {
    console.log(`Worker ${worker.process.pid} exited`);
  });
} else {
  // 工作进程
  (async () => {
    // 打开浏览器
    const browser = await puppeteer.launch();

    // 创建一个新的页面
    const page = await browser.newPage();

    // 设置页面大小
    await page.setViewport({ width: 1280, height: 800 });

    // 循环需要截图的页面
    for (let i = 0; i < 1000; i++) {
      // 打开页面
      await page.goto('https://example.com');

      // 截图
      await page.screenshot({ path: `screenshot-${i}.png` });
    }

    // 关闭浏览器
    await browser.close();
  })();
}

通过使用 cluster 模块,我们可以进一步提高截图性能,充分利用多核 CPU 的优势。

总的来说,Puppeteer 是一个非常强大的工具,可以用来进行网页截图和其他各种操作。通过灵活调整打开浏览器的数量和每个浏览器的标签页数,以及使用 cluster 模块,我们可以进一步优化截图性能,从而满足不同场景的需要。