Puppeteer:如何使用设备框架捕获屏幕截图?

Puppeteer: How to capture a screenshot with device frame?

注意:我在这里问的是这个this closed question的改编版本。

使用Puppeteer时,制作屏幕截图很容易。这甚至是他们的第一个示例,它在我的网络应用程序上运行良好:

const puppeteer = require('puppeteer');
const iPhone = puppeteer.devices['iPhone 6']; //iPhone 5/SE does not work

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.emulate(iPhone);
  await page.goto('https://web.replayer.app', {
    waitUntil: 'networkidle2',
  });
  await page.screenshot({ path: 'replayer-app.png' });

  await browser.close();
})(); 

这会生成一个不错的屏幕截图,但没有设备框架。

如果我尝试使用其中一个设备名称,它会在 Google Chrome 中生成一个可视设备框架,例如 iPhone5/SE,我得到

C:\Users\masu\Documents\node_modules\puppeteer\lib\cjs\puppeteer\common\Page.js:1500
            this.setViewport(options.viewport),
                                     ^

TypeError: Cannot read properties of undefined (reading 'viewport')
    at Page.emulate (C:\Users\masu\Documents\node_modules\puppeteer\lib\cjs\puppeteer\common\Page.js:1500:38)
    at C:\Users\masu\Documents\puppeteer-question.js:7:14
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

但是,由于它是一个网络应用程序,我想让屏幕截图围绕它的设备框架。

如何使用带视口的模拟设备并从中捕获屏幕截图?

问题的原因是什么?

我。您收到此错误是因为您正在使用错误的名称模拟所需的设备。即使 DevTools UI 将其命名为“iPhone 5/SE”,实际上 DevTools 协议只知道“iPhone 5”或“iPhone SE”(您可以尝试一下在这里给出任何错误的字符串,比如“iPhone 2000”,你最终会得到完全相同的错误消息)。 Github 上的 DeviceDescriptors.ts 中列出了可用且有效的设备名称。

二.由于 referenced question 被问及情况仍然相同:您无法在 puppeteer 中使用设备框架对页面进行屏幕截图。仅仅是因为这些框架是 DevTools UI 的一部分,而 Puppeteer 是 high-level API 来控制 Chrome DevTools 协议:一个与其前端相关,另一个与其前端相关后端功能。

如何进行?

  • 自己在 Node 中实现功能。正如我在另一个 post 中提到的:如果您将设备框架作为透明 png 文件,则可以使用 node-images npm 包轻松实现它。例如:images('iPhone_5_portrait.png').draw(images('wikipedia.png').size(320), 130, 220).save('output.jpg').
  • Puppeteer's GitHub 上提出功能请求,但他们不太可能打算这样做(参见上面的 II. 点)。