browserless by vm0-ai/vm0-skills
npx skills add https://github.com/vm0-ai/vm0-skills --skill browserless无头 Chrome 浏览器即服务。无需管理浏览器基础设施,即可截取屏幕截图、生成 PDF、抓取 JavaScript 渲染的页面以及运行 Puppeteer/Playwright 脚本。
当您需要执行以下操作时,请使用此技能:
设置环境变量:
export BROWSERLESS_TOKEN="your-api-token-here"
使用 CSS 选择器提取结构化 JSON:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"elements": [
{"selector": "h1"},
{"selector": "p"}
]
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
使用等待选项:
写入 /tmp/browserless_request.json:
{
"url": "https://news.ycombinator.com",
"elements": [{"selector": ".titleline > a"}],
"gotoOptions": {
"waitUntil": "networkidle2",
"timeout": 30000
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data[0].results[:3]'
全页截图:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"fullPage": true,
"type": "png"
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output screenshot.png
元素截图:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"type": "png"
},
"selector": "h1"
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output element.png
指定视口尺寸:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"viewport": {
"width": 1920,
"height": 1080
},
"options": {
"type": "jpeg",
"quality": 80
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output screenshot.jpg
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"format": "A4",
"printBackground": true,
"margin": {
"top": "1cm",
"bottom": "1cm"
}
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/pdf?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output page.pdf
获取 JavaScript 执行后完全渲染的 HTML:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"gotoOptions": {
"waitUntil": "networkidle0"
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/content?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
运行具有完整交互支持的 Puppeteer 代码:
点击元素:
写入 /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://example.com");
await page.click("a");
return { data: { url: page.url() }, type: "application/json" };
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
在输入框中输入:
写入 /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://duckduckgo.com");
await page.waitForSelector("input[name=q]");
await page.type("input[name=q]", "hello world");
const val = await page.$eval("input[name=q]", e => e.value);
return { data: { typed: val }, type: "application/json" };
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
表单提交:
写入 /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://duckduckgo.com");
await page.type("input[name=q]", "test query");
await page.keyboard.press("Enter");
await page.waitForNavigation();
return { data: { title: await page.title() }, type: "application/json" };
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
使用自定义脚本提取数据:
写入 /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://news.ycombinator.com");
const links = await page.$$eval(".titleline > a", els => els.slice(0,5).map(a => ({title: a.innerText, url: a.href})));
return { data: links, type: "application/json" };
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
绕过机器人检测:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"browserWSEndpoint": false,
"cookies": false,
"content": true,
"screenshot": false
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/unblock?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
启用隐身模式以避免被检测:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"elements": [{"selector": "body"}]
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)&stealth=true" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
获取 URL 并以原生格式获取内容。可以将所有资源(CSS、JS、图片)打包为 zip:
基本导出:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com"
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/export?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output page.html
将所有资源导出为 ZIP:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"includeResources": true
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/export?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output webpage.zip
运行 Lighthouse 审计,检查可访问性、性能、SEO、最佳实践:
完整审计:
写入 /tmp/browserless_request.json:
{
"url": "https://example.com"
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.categories | to_entries[] | {category: .key, score: .value.score}'
特定类别(可访问性、性能、SEO、最佳实践、PWA):
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"config": {
"extends": "lighthouse:default",
"settings": {
"onlyCategories": ["performance"]
}
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.audits | to_entries[:5][] | {audit: .key, score: .value.score, display: .value.displayValue}'
特定审计(例如,未压缩的 CSS、首次内容绘制):
写入 /tmp/browserless_request.json:
{
"url": "https://example.com",
"config": {
"extends": "lighthouse:default",
"settings": {
"onlyAudits": ["first-contentful-paint", "largest-contentful-paint"]
}
}
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.audits'
创建一个可通过 WebSocket 连接的持久浏览器会话:
写入 /tmp/browserless_request.json:
{
"ttl": 300000,
"stealth": false,
"headless": true
}
然后运行:
curl -s -X POST "https://production-sfo.browserless.io/session?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
响应包含:
id - 用于后续操作的会话 IDconnect - 用于 Puppeteer/Playwright 连接的 WebSocket URLstop - 用于停止/删除会话的完整 URL(请使用此确切 URL)browserQL - BrowserQL 查询端点ttl - 生存时间(毫秒)(默认值:300000 = 5 分钟)使用 Puppeteer 连接会话:
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({
browserWSEndpoint: '<connect-url-from-response>' // 使用响应中的 'connect' URL
});
在超时到期前,使用创建响应中的 stop URL 停止正在运行的会话:
curl -s -X DELETE "<stop-url-from-response>"
示例(将 <stop-url-from-response> 替换为会话创建时返回的实际 stop URL):
curl -s -X DELETE "https://production-sfo.browserless.io/e/<encoded-path>/session/<session-id>?token=<your-token>"
响应:
{
"success": true,
"message": "Session <session-id> was successfully removed",
"sessionId": "<session-id>",
"timestamp": "2026-01-01T07:41:36.933Z"
}
| 端点 | 方法 | 描述 |
|---|---|---|
/scrape | POST | 使用 CSS 选择器提取数据 |
/screenshot | POST | 截取屏幕截图(PNG/JPEG) |
/pdf | POST | 生成 PDF 文档 |
/content | POST | 获取渲染后的 HTML |
/function | POST | 执行自定义 Puppeteer 代码 |
/unblock | POST | 绕过机器人保护 |
/export | POST | 将页面及资源导出为 ZIP |
/performance | POST | Lighthouse 审计(可访问性、性能、SEO) |
/session | POST | 创建持久浏览器会话 |
/session/{id} | DELETE | 停止持久会话 |
控制页面导航:
{
"gotoOptions": {
"waitUntil": "networkidle2",
"timeout": 30000
}
}
waitUntil 值:
load - 等待 load 事件domcontentloaded - 等待 DOMContentLoaded 事件networkidle0 - 500 毫秒内无网络连接networkidle2 - 500 毫秒内最多有 2 个网络连接{
"waitForTimeout": 1000,
"waitForSelector": {"selector": ".loaded", "timeout": 5000},
"waitForFunction": {"fn": "() => document.ready", "timeout": 5000}
}
{
"viewport": {
"width": 1920,
"height": 1080,
"deviceScaleFactor": 2
}
}
| 参数 | 描述 |
|---|---|
token | API 令牌(必需) |
stealth | 启用隐身模式(true/false) |
blockAds | 拦截广告 |
proxy | 使用代理服务器 |
抓取响应:
{
"data": [
{
"selector": "h1",
"results": [
{
"text": "Example Domain",
"html": "Example Domain",
"attributes": [{"name": "class", "value": "title"}],
"width": 400,
"height": 50,
"top": 100,
"left": 50
}
]
}
]
}
networkidle2,对于单页应用使用 networkidle0jpeg 格式并设置质量为 80 以获得更小的文件production-sfo.browserless.io(美国西部)production-lon.browserless.io(欧洲)每周安装数
112
代码仓库
GitHub 星标数
48
首次出现时间
2026年1月24日
安全审计
安装于
opencode94
gemini-cli93
codex90
cursor86
github-copilot86
amp84
Headless Chrome browser as a service. Take screenshots, generate PDFs, scrape JS-rendered pages, and run Puppeteer/Playwright scripts without managing browser infrastructure.
Official docs: https://docs.browserless.io/
Use this skill when you need to:
Set environment variable:
export BROWSERLESS_TOKEN="your-api-token-here"
Extract structured JSON using CSS selectors:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"elements": [
{"selector": "h1"},
{"selector": "p"}
]
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
With wait options:
Write to /tmp/browserless_request.json:
{
"url": "https://news.ycombinator.com",
"elements": [{"selector": ".titleline > a"}],
"gotoOptions": {
"waitUntil": "networkidle2",
"timeout": 30000
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data[0].results[:3]'
Full page screenshot:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"fullPage": true,
"type": "png"
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output screenshot.png
Element screenshot:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"type": "png"
},
"selector": "h1"
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output element.png
With viewport size:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"viewport": {
"width": 1920,
"height": 1080
},
"options": {
"type": "jpeg",
"quality": 80
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output screenshot.jpg
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"format": "A4",
"printBackground": true,
"margin": {
"top": "1cm",
"bottom": "1cm"
}
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/pdf?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output page.pdf
Get fully rendered HTML after JavaScript execution:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"gotoOptions": {
"waitUntil": "networkidle0"
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/content?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
Run Puppeteer code with full interaction support:
Click element:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://example.com");
await page.click("a");
return { data: { url: page.url() }, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Type into input:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://duckduckgo.com");
await page.waitForSelector("input[name=q]");
await page.type("input[name=q]", "hello world");
const val = await page.$eval("input[name=q]", e => e.value);
return { data: { typed: val }, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Form submission:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://duckduckgo.com");
await page.type("input[name=q]", "test query");
await page.keyboard.press("Enter");
await page.waitForNavigation();
return { data: { title: await page.title() }, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Extract data with custom script:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://news.ycombinator.com");
const links = await page.$$eval(".titleline > a", els => els.slice(0,5).map(a => ({title: a.innerText, url: a.href})));
return { data: links, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Bypass bot detection:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"browserWSEndpoint": false,
"cookies": false,
"content": true,
"screenshot": false
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/unblock?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
Enable stealth mode to avoid detection:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"elements": [{"selector": "body"}]
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)&stealth=true" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
Fetch a URL and get content in native format. Can bundle all resources (CSS, JS, images) as zip:
Basic export:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com"
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/export?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output page.html
Export with all resources as ZIP:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"includeResources": true
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/export?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output webpage.zip
Run Lighthouse audits for accessibility, performance, SEO, best practices:
Full audit:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com"
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.categories | to_entries[] | {category: .key, score: .value.score}'
Specific category (accessibility, performance, seo, best-practices, pwa):
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"config": {
"extends": "lighthouse:default",
"settings": {
"onlyCategories": ["performance"]
}
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.audits | to_entries[:5][] | {audit: .key, score: .value.score, display: .value.displayValue}'
Specific audit (e.g., unminified-css, first-contentful-paint):
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"config": {
"extends": "lighthouse:default",
"settings": {
"onlyAudits": ["first-contentful-paint", "largest-contentful-paint"]
}
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.audits'
Create a persistent browser session that can be connected to via WebSocket:
Write to /tmp/browserless_request.json:
{
"ttl": 300000,
"stealth": false,
"headless": true
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/session?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
Response includes:
id - Session ID for subsequent operationsconnect - WebSocket URL for Puppeteer/Playwright connectionstop - Full URL to stop/delete the session (use this exact URL)browserQL - BrowserQL query endpointttl - Time-to-live in milliseconds (default: 300000 = 5 minutes)Use the session with Puppeteer:
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({
browserWSEndpoint: '<connect-url-from-response>' // Use the 'connect' URL from response
});
Stop a running session before its timeout expires using the stop URL from the creation response:
curl -s -X DELETE "<stop-url-from-response>"
Example (replace <stop-url-from-response> with the actual stop URL from session creation):
curl -s -X DELETE "https://production-sfo.browserless.io/e/<encoded-path>/session/<session-id>?token=<your-token>"
Response:
{
"success": true,
"message": "Session <session-id> was successfully removed",
"sessionId": "<session-id>",
"timestamp": "2026-01-01T07:41:36.933Z"
}
| Endpoint | Method | Description |
|---|---|---|
/scrape | POST | Extract data with CSS selectors |
/screenshot | POST | Capture screenshots (PNG/JPEG) |
/pdf | POST | Generate PDF documents |
/content | POST | Get rendered HTML |
/function | POST | Execute custom Puppeteer code |
Control page navigation:
{
"gotoOptions": {
"waitUntil": "networkidle2",
"timeout": 30000
}
}
waitUntil values:
load - Wait for load eventdomcontentloaded - Wait for DOMContentLoadednetworkidle0 - No network connections for 500msnetworkidle2 - Max 2 network connections for 500ms{
"waitForTimeout": 1000,
"waitForSelector": {"selector": ".loaded", "timeout": 5000},
"waitForFunction": {"fn": "() => document.ready", "timeout": 5000}
}
{
"viewport": {
"width": 1920,
"height": 1080,
"deviceScaleFactor": 2
}
}
| Parameter | Description |
|---|---|
token | API token (required) |
stealth | Enable stealth mode (true/false) |
blockAds | Block advertisements |
proxy | Use proxy server |
Scrape response:
{
"data": [
{
"selector": "h1",
"results": [
{
"text": "Example Domain",
"html": "Example Domain",
"attributes": [{"name": "class", "value": "title"}],
"width": 400,
"height": 50,
"top": 100,
"left": 50
}
]
}
]
}
networkidle2 for most pages, networkidle0 for SPAsjpeg with quality 80 for smaller filesproduction-sfo.browserless.io (US West)production-lon.browserless.io (Europe)Weekly Installs
112
Repository
GitHub Stars
48
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode94
gemini-cli93
codex90
cursor86
github-copilot86
amp84
Azure 升级评估与自动化工具 - 轻松迁移 Functions 计划、托管层级和 SKU
96,200 周安装
/unblock | POST | Bypass bot protection |
/export | POST | Export page with resources as ZIP |
/performance | POST | Lighthouse audits (a11y, perf, SEO) |
/session | POST | Create persistent browser session |
/session/{id} | DELETE | Stop persistent session |