Puppeteer ↗ 是最流行的库之一,它为开发者抽象了较低级别的 DevTools 协议,提供高级 API,可轻松检测 Chrome/Chromium 并自动化浏览会话。Puppeteer 用于创建屏幕截图、爬取页面和测试 Web 应用等任务。
Puppeteer 通常通过 DevTools 端口连接到本地 Chrome 或 Chromium 浏览器。更多信息请参阅 Puppeteer API 文档中的 Puppeteer.connect() 方法 ↗。
Workers 团队 fork 了 Puppeteer 的一个版本,并进行了修改以连接到 Workers Browser Run API 而非本地浏览器。连接后,开发者可以像在标准设置中一样使用完整的 Puppeteer API ↗。
我们的版本已开源,可在 Cloudflare 的 Puppeteer fork ↗ 中找到。npm 包可从 npmjs ↗ 安装为 @cloudflare/puppeteer ↗:
npm i -D @cloudflare/puppeteeryarn add -D @cloudflare/puppeteerpnpm add -D @cloudflare/puppeteerbun add -d @cloudflare/puppeteer配置 browser 绑定 并安装 @cloudflare/puppeteer 库后,即可在 Worker 中使用 Puppeteer:
import puppeteer from "@cloudflare/puppeteer";
export default {
async fetch(request, env) {
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto("https://example.com");
const metrics = await page.metrics();
await browser.close();
return Response.json(metrics);
},
};import puppeteer from "@cloudflare/puppeteer";
interface Env {
MYBROWSER: Fetcher;
}
export default {
async fetch(request, env): Promise<Response> {
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto("https://example.com");
const metrics = await page.metrics();
await browser.close();
return Response.json(metrics);
},
} satisfies ExportedHandler<Env>;此脚本启动 ↗ env.MYBROWSER 浏览器,打开新页面 ↗,导航到 ↗ https://example.com/ ↗,获取页面加载指标 ↗,关闭 ↗浏览器并以 JSON 格式打印指标。
如果用户省略 browser.close() 语句,浏览器将保持打开,可随时再次连接并复用,但默认情况下会在 1 分钟不活动后自动关闭。用户可以选择使用 keep_alive 选项(以毫秒为单位)将空闲时间延长至最多 10 分钟:
const browser = await puppeteer.launch(env.MYBROWSER, { keep_alive: 600000 });使用上述配置,即使不活动,浏览器也会保持打开最多 10 分钟。
要在 Puppeteer 中指定自定义 user agent,使用 page.setUserAgent() 方法。当目标网站根据 user agent 提供不同内容时很有用。
await page.setUserAgent(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
);使用 wrangler dev 或 vite dev 进行本地开发时,Chrome 默认以 headless 模式运行。要以可见(headful)模式启动 Chrome,请设置 X_BROWSER_HEADFUL 环境变量:
X_BROWSER_HEADFUL=true npx wrangler dev或使用 Cloudflare Vite 插件:
X_BROWSER_HEADFUL=true npx vite dev这将打开浏览器窗口,以便实时观看 Puppeteer 自动化,更易于调试导航、元素选择和页面交互。
Puppeteer 提供多种在页面上选择元素的方法。CSS 选择器按预期工作,但由于 Workers 运行时的安全约束,不支持 XPath 选择器。
你可以使用 CSS 选择器或 page.evaluate() 在浏览器上下文中运行 XPath 查询,而非使用 XPath 选择器:
const innerHtml = await page.evaluate(() => {
return (
// @ts-ignore this runs on browser context
new XPathEvaluator()
.createExpression("/html/body/div/h1")
// @ts-ignore this runs on browser context
.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue
.innerHTML
);
});为了便于浏览器会话管理,我们为 puppeteer 添加了新方法:
puppeteer.sessions() 列出当前运行的会话。它将返回类似以下的输出:
[
{
"connectionId": "2a2246fa-e234-4dc1-8433-87e6cee80145",
"connectionStartTime": 1711621704607,
"sessionId": "478f4d7d-e943-40f6-a414-837d3736a1dc",
"startTime": 1711621703708
},
{
"sessionId": "565e05fb-4d2a-402b-869b-5b65b1381db7",
"startTime": 1711621703808
}
]注意会话 478f4d7d-e943-40f6-a414-837d3736a1dc 有活动的 worker 连接(connectionId=2a2246fa-e234-4dc1-8433-87e6cee80145),而会话 565e05fb-4d2a-402b-869b-5b65b1381db7 是空闲的。连接处于活动状态时,其他 worker 无法连接到该会话。
puppeteer.history() 列出最近的会话,包括打开和已关闭的。它有助于了解当前用量。
[
{
"closeReason": 2,
"closeReasonText": "BrowserIdle",
"endTime": 1711621769485,
"sessionId": "478f4d7d-e943-40f6-a414-837d3736a1dc",
"startTime": 1711621703708
},
{
"closeReason": 1,
"closeReasonText": "NormalClosure",
"endTime": 1711123501771,
"sessionId": "2be00a21-9fb6-4bb2-9861-8cd48e40e771",
"startTime": 1711123430918
}
]会话 2be00a21-9fb6-4bb2-9861-8cd48e40e771 由客户端显式调用 browser.close() 关闭,而会话 478f4d7d-e943-40f6-a414-837d3736a1dc 因达到最大空闲时间而关闭(查看限制)。
你也应该能够在仪表板中访问此信息,尽管可能略有延迟。
puppeteer.limits() 列出你的活动限制:
{
"activeSessions": [
{ "id": "478f4d7d-e943-40f6-a414-837d3736a1dc" },
{ "id": "565e05fb-4d2a-402b-869b-5b65b1381db7" }
],
"allowedBrowserAcquisitions": 1,
"maxConcurrentSessions": 2,
"timeUntilNextAllowedBrowserAcquisition": 0
}activeSessions列出当前打开会话的 IDmaxConcurrentSessions定义可同时打开多少个浏览器allowedBrowserAcquisitions指定根据当前速率限制是否可以打开新的浏览器会话timeUntilNextAllowedBrowserAcquisition定义启动新浏览器前的等待时间
完整的 Puppeteer API 可在 Cloudflare 的 Puppeteer fork ↗ 中找到。