Loading...
Loading...
Compare original and translation side by side
{
"name": "browser-worker",
"main": "src/index.ts",
"compatibility_date": "2023-03-14",
"compatibility_flags": ["nodejs_compat"],
"browser": {
"binding": "MYBROWSER"
}
}{
"name": "browser-worker",
"main": "src/index.ts",
"compatibility_date": "2023-03-14",
"compatibility_flags": ["nodejs_compat"],
"browser": {
"binding": "MYBROWSER"
}
}bun add @cloudflare/puppeteerbun add @cloudflare/puppeteerimport puppeteer from "@cloudflare/puppeteer";
interface Env {
MYBROWSER: Fetcher;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { searchParams } = new URL(request.url);
const url = searchParams.get("url") || "https://example.com";
// Launch browser
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
// Navigate and capture
await page.goto(url);
const screenshot = await page.screenshot();
// Clean up
await browser.close();
return new Response(screenshot, {
headers: { "content-type": "image/png" }
});
}
};import puppeteer from "@cloudflare/puppeteer";
interface Env {
MYBROWSER: Fetcher;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { searchParams } = new URL(request.url);
const url = searchParams.get("url") || "https://example.com";
// Launch browser
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
// Navigate and capture
await page.goto(url);
const screenshot = await page.screenshot();
// Clean up
await browser.close();
return new Response(screenshot, {
headers: { "content-type": "image/png" }
});
}
};bunx wrangler deployhttps://your-worker.workers.dev/?url=https://example.comenv.MYBROWSERpuppeteer.launch()browser.close()browser.disconnect()nodejs_compatbunx wrangler deployhttps://your-worker.workers.dev/?url=https://example.comenv.MYBROWSERpuppeteer.launch()browser.close()browser.disconnect()nodejs_compatpuppeteer-api.mdpatterns.mdsession-management.mdpricing-and-limits.mdcommon-errors.mdpuppeteer-vs-playwright.mdpatterns.mdcommon-errors.mdpricing-and-limits.mdsession-management.mdpuppeteer-api.mdpuppeteer-api.mdpatterns.mdsession-management.mdpricing-and-limits.mdcommon-errors.mdpuppeteer-vs-playwright.mdpatterns.mdcommon-errors.mdpricing-and-limits.mdsession-management.mdpuppeteer-api.md| Method | Best For | Complexity |
|---|---|---|
| Workers Bindings | Complex automation, custom workflows, session management | Advanced |
| REST API | Simple screenshot/PDF tasks | Simple |
| 方式 | 适用场景 | 复杂度 |
|---|---|---|
| Workers绑定 | 复杂自动化、自定义工作流、会话管理 | 高级 |
| REST API | 简单的截图/PDF任务 | 简单 |
| Feature | Puppeteer | Playwright |
|---|---|---|
| API Familiarity | Most popular | Growing adoption |
| Package | | |
| Session Management | ✅ Advanced APIs | ⚠️ Basic |
| Browser Support | Chromium only | Chromium only (Firefox/Safari not yet supported) |
| Best For | Screenshots, PDFs, scraping | Testing, frontend automation |
| 特性 | Puppeteer | Playwright |
|---|---|---|
| API熟悉度 | 最受欢迎 | 采用率持续增长 |
| 包 | | |
| 会话管理 | ✅ 高级API | ⚠️ 基础功能 |
| 浏览器支持 | 仅Chromium | 仅Chromium(暂不支持Firefox/Safari) |
| 适用场景 | 截图、PDF、抓取 | 测试、前端自动化 |
launch()connect()sessions()history()limits()newPage()sessionId()close()disconnect()createBrowserContext()goto()screenshot()pdf()content()setContent()evaluate()waitForSelector()type()click()const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto("https://example.com");
const screenshot = await page.screenshot({ fullPage: true });
await browser.close();references/puppeteer-api.mdlaunch()connect()sessions()history()limits()newPage()sessionId()close()disconnect()createBrowserContext()goto()screenshot()pdf()content()setContent()evaluate()waitForSelector()type()click()const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto("https://example.com");
const screenshot = await page.screenshot({ fullPage: true });
await browser.close();references/puppeteer-api.mdbun add @cloudflare/playwrightbun add @cloudflare/playwrightimport { env } from "cloudflare:test";
import { chromium } from "@cloudflare/playwright";
interface Env {
BROWSER: Fetcher;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const browser = await chromium.launch(env.BROWSER);
const page = await browser.newPage();
await page.goto("https://example.com");
const screenshot = await page.screenshot();
await browser.close();
return new Response(screenshot, {
headers: { "content-type": "image/png" }
});
}
};import { env } from "cloudflare:test";
import { chromium } from "@cloudflare/playwright";
interface Env {
BROWSER: Fetcher;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const browser = await chromium.launch(env.BROWSER);
const page = await browser.newPage();
await page.goto("https://example.com");
const screenshot = await page.screenshot();
await browser.close();
return new Response(screenshot, {
headers: { "content-type": "image/png" }
});
}
};| Feature | Puppeteer | Playwright |
|---|---|---|
| Import | | |
| Launch | | |
| Session API | ✅ Advanced (sessions, history, limits) | ⚠️ Basic |
| Auto-waiting | Manual | Built-in auto-waiting |
| Selectors | CSS only | CSS, text, XPath (via evaluate workaround) |
| 特性 | Puppeteer | Playwright |
|---|---|---|
| 导入方式 | | |
| 启动方式 | | |
| 会话API | ✅ 高级功能(会话、历史记录、限制) | ⚠️ 基础功能 |
| 自动等待 | 手动调用 | 内置自动等待 |
| 选择器 | 仅CSS | CSS、文本、XPath(通过evaluate变通实现) |
puppeteer.sessions()puppeteer.connect()newPage()disconnect()close()references/session-management.mdpuppeteer.sessions()puppeteer.connect()newPage()disconnect()close()references/session-management.mdconst browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto(url);
const screenshot = await page.screenshot({ fullPage: true });
await env.CACHE.put(url, screenshot, { expirationTtl: 86400 });
await browser.close();references/patterns.mdconst browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto(url);
const screenshot = await page.screenshot({ fullPage: true });
await env.CACHE.put(url, screenshot, { expirationTtl: 86400 });
await browser.close();references/patterns.mdreferences/pricing-and-limits.mdreferences/pricing-and-limits.mdpage.evaluate()// ❌ Don't use XPath directly (not supported)
// await page.$x('/html/body/div/h1')
// ✅ Use CSS selector
const heading = await page.$("div > h1");
// ✅ Or use XPath in page.evaluate()
const innerHtml = await page.evaluate(() => {
return new XPathEvaluator()
.createExpression("/html/body/div/h1")
.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE)
.singleNodeValue.innerHTML;
});page.evaluate()// ❌ 不要直接使用XPath(不支持)
// await page.$x('/html/body/div/h1')
// ✅ 使用CSS选择器
const heading = await page.$("div > h1");
// ✅ 或在page.evaluate()中使用XPath
const innerHtml = await page.evaluate(() => {
return new XPathEvaluator()
.createExpression("/html/body/div/h1")
.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE)
.singleNodeValue.innerHTML;
});puppeteer.launch()env.MYBROWSER// ❌ Missing browser binding
const browser = await puppeteer.launch(); // Error!
// ✅ Pass binding
const browser = await puppeteer.launch(env.MYBROWSER);puppeteer.launch()env.MYBROWSER// ❌ 缺少浏览器绑定
const browser = await puppeteer.launch(); // 报错!
// ✅ 传入绑定
const browser = await puppeteer.launch(env.MYBROWSER);keep_alive// Extend timeout to 5 minutes for long-running tasks
const browser = await puppeteer.launch(env.MYBROWSER, {
keep_alive: 300000 // 5 minutes = 300,000 ms
});keep_alive// 为长时间运行的任务将超时延长至5分钟
const browser = await puppeteer.launch(env.MYBROWSER, {
keep_alive: 300000 // 5分钟 = 300,000 毫秒
});references/common-errors.mdreferences/common-errors.mdnodejs_compatreferences/patterns.mdnodejs_compatreferences/patterns.md@cloudflare/puppeteer@1.0.4wrangler@4.50.0@cloudflare/workers-types@4.20251125.0cloudflare-worker-basecloudflare-kvcloudflare-workers-ai@cloudflare/puppeteer@1.0.4wrangler@4.50.0@cloudflare/workers-types@4.20251125.0cloudflare-worker-basecloudflare-kvcloudflare-workers-ai{
"dependencies": {
"@cloudflare/puppeteer": "^1.0.4"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20251125.0",
"wrangler": "^4.50.0"
}
}{
"dependencies": {
"@cloudflare/playwright": "^1.0.0"
}
}{
"dependencies": {
"@cloudflare/puppeteer": "^1.0.4"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20251125.0",
"wrangler": "^4.50.0"
}
}{
"dependencies": {
"@cloudflare/playwright": "^1.0.0"
}
}const browser = await puppeteer.launch(env.MYBROWSER); // Not just puppeteer.launch()const browser = await puppeteer.launch(env.MYBROWSER); // 不要只调用puppeteer.launch()const browser = await puppeteer.launch(env.MYBROWSER, { keep_alive: 300000 });const browser = await puppeteer.launch(env.MYBROWSER, { keep_alive: 300000 });{ "browser": { "binding": "MYBROWSER", "remote": true } }{ "browser": { "binding": "MYBROWSER", "remote": true } }references/common-errors.mdreferences/session-management.mdnodejs_compatreferences/common-errors.mdreferences/session-management.mdnodejs_compat