《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过DevTools 协议控制 Chrome 或 Chromium 。
Puppeteer特性
- 生成页面的屏幕截图和 PDF。
- 抓取 SPA(单页应用程序)并生成预渲染内容(即“SSR”(服务器端渲染))。
- 自动化表单提交、UI 测试、键盘输入等。
- 创建最新的自动化测试环境。使用最新的 JavaScript 和浏览器功能直接在最新版本的 Chrome 中运行测试。
- 捕获您网站的时间线轨迹以帮助诊断性能问题。
- 测试 Chrome 扩展程序。
开始使用
要在您的项目中使用 Puppeteer,请运行:
npm i puppeteer
# or "yarn add puppeteer"
当您安装 Puppeteer 时,它会下载最新版本的 Chromium(~170MB Mac、~282MB Linux、~280MB Win),保证可以与 API 一起使用(可通过环境变量自定义)。有关纯粹用于连接的 Puppeteer 版本,请参阅puppeteer-core。
环境变量
Puppeteer 会寻找某些环境变量来帮助其操作。如果 Puppeteer 在安装步骤中没有在环境中找到它们,则会从npm config使用这些变量的小写变体。
- HTTP_PROXY, HTTPS_PROXY, NO_PROXY- 定义用于下载和运行浏览器的 HTTP 代理设置。
- PUPPETEER_SKIP_CHROMIUM_DOWNLOAD- 不要在安装步骤中下载捆绑的 Chromium。
- PUPPETEER_TMP_DIR- 定义 Puppeteer 用于创建临时文件的目录。默认为os.tmpdir().
- PUPPETEER_DOWNLOAD_HOST- 覆盖用于下载 Chromium 的 URL 前缀。注意:这包括协议,甚至可能包括路径前缀。默认为https://storage.googleapis.com。
- PUPPETEER_DOWNLOAD_PATH- 覆盖下载文件夹的路径。默认为
/.local-chromium, Puppeteer 的包根在哪里。 - PUPPETEER_CHROMIUM_REVISION- 指定您希望 Puppeteer 使用的特定版本的 Chromium。查看puppeteer.launch如何推断可执行路径。
- PUPPETEER_EXECUTABLE_PATH- 指定要在puppeteer.launch。
- PUPPETEER_PRODUCT- 指定您希望 Puppeteer 使用的浏览器。必须是chrome或之一firefox。这也可以在安装期间用于获取推荐的浏览器二进制文件。product以编程方式设置puppeteer.launch取代此环境变量。产品暴露在puppeteer.product。
- PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM— 为 Apple M1 指定 Puppeteer 下载 Chromium。在 Apple M1 设备上,Puppeteer 默认下载通过 Rosetta 运行的英特尔处理器版本。它可以毫无问题地工作,但是,使用此选项,您应该获得更有效的资源使用(CPU 和 RAM),这可能会导致更快的执行时间。
默认运行时设置
使用无头模式
Puppeteer 以无头模式启动 Chromium 。要启动完整版 Chromium,请在启动浏览器时设置headless选项:
const browser = await puppeteer.launch({headless: false}); // default is true
运行 Chromium 的捆绑版本
默认情况下,Puppeteer 下载并使用特定版本的 Chromium,因此它的 API 可以保证开箱即用。要将 Puppeteer 与不同版本的 Chrome 或 Chromium 一起使用,请在创建Browser实例时传入可执行文件的路径:
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
您还可以将 Puppeteer 与 Firefox Nightly 一起使用(实验性支持)。
this article有关Chromium 和 Chrome 之间差异的描述,请参阅。
创建一个新的用户配置文件
Puppeteer 创建自己的浏览器用户配置文件,每次运行都会对其进行清理。
示例
示例- 导航到https://example.com并将屏幕截图保存为example.png:
将文件另存为example.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
在命令行执行脚本
node example.js
Puppeteer 将初始页面大小设置为 800×600px,它定义了屏幕截图的大小。页面大小可以自定义Page.setViewport()。
示例- 创建 PDF。
将文件另存为hn.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {
waitUntil: 'networkidle2',
});
await page.pdf({path: 'hn.pdf', format: 'a4'});
await browser.close();
})();
在命令行执行脚本
node hn.js
Page.pdf有关创建 pdf 的更多信息。
示例- 在页面上下文中评估脚本
将文件另存为get-dimensions.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// Get the "viewport" of the page, as reported by the page.
const dimensions = await page.evaluate(() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
};
});
console.log('Dimensions:', dimensions);
await browser.close();
})();
在命令行执行脚本
node get-dimensions.js
请参阅Page.evaluate和相关的方法,如
Page.evaluateOnNewDocument和Page.exposeFunction。
Docker
Puppeteer 提供了一个 Docker 映像,其中包括 Chromium 以及所需的依赖项和预安装的 Puppeteer 版本。该图像可通过GitHub Container Registry获得。最新的图像被标记为latest和其他标签匹配 Puppeteer 版本。例如,
docker pull ghcr.io/puppeteer/puppeteer:latest # pulls the latest
docker pull ghcr.io/puppeteer/puppeteer:16.1.0 # pulls the image that contains Puppeteer v16.1.0
该图像用于在沙盒模式下运行浏览器,因此,运行该图像需要该SYS_ADMIN功能。例如,
docker run -i --init --cap-add=SYS_ADMIN --rm ghcr.io/puppeteer/puppeteer:latest node -e "`cat docker/test/smoke-test.js`"
将路径替换为smoke-test.js脚本的路径。该脚本可以导入或需要puppeteer模块,因为它已预先安装在映像中。
目前,该镜像包含 LTS 版本的 Node.js。如果您需要基于不同的基础镜像构建镜像,您可以使用我们的Dockerfile作为起点。
API指南
创作新的 API 方法时,请考虑以下事项:
- 根据需要公开尽可能少的信息。如有疑问,请勿公开新信息
- 方法用于支持 getter/setter。唯一的例外是命名空间,例如page.keyboard和page.coverage
- 所有字符串文字必须小写。这包括事件名称和选项值
运行和写作测试
- 每个功能都应该伴随着测试。
- 每个公共 api 事件/方法都应附有测试。
- 测试不应依赖于外部服务。
- 测试应该适用于所有三个平台:Mac、Linux 和 Win。这对于屏幕截图测试尤其重要。
Puppeteer 测试位于该test目录中,并使用 Mocha 编写。
尽管被命名为“单元”,但这些都是集成测试,确保公共 API 方法和事件按预期工作。
—END—
开源协议:Apache-2.0
开源地址:
https://github.com/puppeteer/puppeteer