Run Playwright scripts that share OpenClaw browser's login state via CDP, with automatic conflict avoidance. Use when: (1) recording browser tool operations as reusable Playwright scripts, (2) running headless automation that needs existing cookies/sessions, (3) scheduling browser tasks in cron without CDP conflicts, (4) converting exploratory browser tool workflows into zero-token repeatable scripts.
OpenClaw的浏览器工具和外部Playwright脚本无法同时共享同一个CDP连接。本技能提供了一种基于锁的桥接方案:停止OpenClaw浏览器 → 使用相同的Chrome配置文件(保留cookies/登录状态)运行Playwright → 释放锁以便OpenClaw重新连接。
Chrome (CDP端口) ← 共享用户数据目录 (~/.openclaw/browser/openclaw/user-data)
↕ 互斥访问
┌──────────────┐ ┌──────────────────┐
│ OpenClaw │ 或 │ Playwright脚本 │
│ 浏览器工具 │ │ (零token成本) │
└──────────────┘ └──────────────────┘
↕ 由 browser-lock.sh 管理
bash
cd <工作区目录> && npm install playwright
注意: 不需要执行 npx playwright install。Playwright通过CDP连接到现有的Chrome——无需下载本地浏览器。
bash
chmod +x scripts/browser-lock.sh
CDP端口是动态分配的。切勿硬编码。 使用 discoverCdpUrl()(见下文)或 browser-lock.sh 中的shell等效方法。
Shell单行命令:
bash
ps aux | grep remote-debugging-port= | grep -v grep | grep -o remote-debugging-port=[0-9]* | head -1 | cut -d= -f2
验证CDP是否响应:
bash
curl -s --max-time 1 http://127.0.0.1:<端口>/json/version
bash
./scripts/browser-lock.sh run scripts/my-task.js [参数...]
./scripts/browser-lock.sh run --timeout 120 scripts/my-task.js # 自定义超时
默认超时:300秒。如果脚本超时,看门狗会终止它并释放锁。
此命令自动执行:检查锁 → 停止OpenClaw浏览器 → 启动带CDP的Chrome → 运行脚本 → 清理 → 释放锁。
bash
./scripts/browser-lock.sh acquire # 停止OpenClaw浏览器,启动Chrome
node scripts/my-task.js # 运行脚本
./scripts/browser-lock.sh release # 终止Chrome,释放锁
bash
./scripts/browser-lock.sh status
使用 scripts/playwright-template.js 作为起点。
所有脚本应使用 discoverCdpUrl() 而非硬编码端口:
javascript
const { execSync } = require(child_process);
/
* 通过检查Chrome进程参数发现CDP URL。
* 回退到CDP_PORT环境变量,然后探测常用端口。
*/
function discoverCdpUrl() {
// 方法1:从正在运行的Chrome进程中提取
try {
const ps = execSync(
ps aux | grep remote-debugging-port= | grep -v grep,
{ encoding: utf8, timeout: 3000 }
);
const match = ps.match(/remote-debugging-port=(\d+)/);
if (match) return http://127.0.0.1:${match[1]};
} catch {}
// 方法2:CDP_PORT环境变量
if (process.env.CDP_PORT) {
return http://127.0.0.1:${process.env.CDP_PORT};
}
// 方法3:探测常用端口
// 18800是典型的OpenClaw默认端口;其他是常见的CDP约定端口
const { execSync: probe } = require(child_process);
for (const port of [18800, 9222, 9229]) {
try {
probe(curl -s --max-time 1 http://127.0.0.1:${port}/json/version, {
encoding: utf8, timeout: 2000
});
return http://127.0.0.1:${port};
} catch {}
}
throw new Error(未找到CDP端口。Chrome是否以--remote-debugging-port参数运行?);
}
javascript
const { chromium } = require(playwright);
async function main() {
let browser;
try {
browser = await chromium.connectOverCDP(discoverCdpUrl());
} catch (e) {
console.error(❌ 无法连接到Chrome CDP:, e.message);
console.error( 请确保已调用 browser-lock.sh acquire,或Chrome以--remote-debugging-port参数运行);
process.exit(1);
}
const context = browser.contexts()[0]; // 重用现有上下文(保留cookies!)
const page = await context.newPage();
try {
// ====== 在此编写自动化代码 ======
await page.goto(https://example.com);
console.log(页面标题:, await page.title());
// ==================================
} catch (e) {
console.error(❌ 脚本错误:, e.message);
throw e;
} finally {
await page.close(); // 仅关闭你的标签页
// 切勿调用 browser.close() —— 它会终止整个Chrome进程
}
}
main().then(() => process.exit(0)).catch(e => {
console.error(❌, e.message);
process.exit(1);
});
关键规则:
在定时任务中,直接调用 browser-lock.sh:
bash
cd /path/to/workspace && ./scripts/browser-lock.sh run scripts/publish-task.js
锁文件(/tmp/openclaw-browser.lock)防止并发浏览器访问。如果锁已过期(拥有进程已死亡),会自动恢复。
| 问题 | 解决方法 |
|---|---|
| 锁被PID xxx持有 | 执行 ./scripts/browser-lock.sh release 强制释放 |
| Playwright connectOverCDP超时 |
| 变量 | 默认值 | 描述 |
|---|---|---|
| CDPPORT | 自动发现 | 覆盖CDP端口(跳过进程检测) |
| CHROMEBIN |
该技能支持在以下平台通过对话安装:
帮我安装 SkillHub 和 browser-playwright-bridge-1776304286 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 browser-playwright-bridge-1776304286 技能
skillhub install browser-playwright-bridge-1776304286
文件大小: 8.64 KB | 发布时间: 2026-4-16 18:02