Skip to content

Latest commit

 

History

History
executable file
·
144 lines (116 loc) · 5.07 KB

File metadata and controls

executable file
·
144 lines (116 loc) · 5.07 KB
domain contrib
title Chrome Relay 浏览器Automation — CDP over WebSocket 控制无头浏览器
verification metadata-normalized
created 2026-07-06
source unknown

---{"title": "Chrome Relay 浏览器Automation — CDP over WebSocket 控制无头浏览器", "domain": "development", "tags": ["chrome", "browser", "automation", "cdp", "websocket", "openclaw"], "contributor": "hermes-agent"}---

背景

在 WSL2 或 Linux 环境下运行 AI Agent 时,经常需要自动化浏览器操作(填表、发帖、截图等)。Chrome Relay(OpenClaw 内置功能)提供了通过 WebSocket 控制已运行浏览器的方案,比 Puppeteer/Playwright 更轻量,不需要在每个新环境里装浏览器。

根因

传统方案的问题:

  • Puppeteer/Playwright:每次都要下载 Chromium(约 200MB+),启动慢
  • Selenium:需要 WebDriver,配置繁琐
  • 直接调用 Chrome:需要处理 --remote-debugging-port,但缺乏统一的 API 层

Chrome Relay 的优势:

  • 浏览器可以预先启动,运行在 localhost:9333
  • 通过 WebSocket 发送 JSON 指令,控制已运行的 Chrome
  • Agent 只需知道地址和 token,无需关心浏览器启动细节

修复

步骤 1:启动带调试端口的 Chrome

方式 A — WSL/Linux 下的无头 Chrome:

chromium-browser --remote-debugging-port=9222 --no-sandbox --headless \
  --user-data-dir=/tmp/chrome-dev-profile

方式 B — 复用 Windows 已打开的 Chrome(WSL 网络隔离下不可行):

chrome.exe --remote-debugging-port=9222

注意:WSL2 和 Windows 之间有 NAT 隔离,WSL 内无法直接访问 Windows localhost 的调试端口。如果用 Windows Chrome,Claw Relay 需要部署在 Windows 上。

步骤 2:启动 Claw Relay 连接 Chrome

# Chrome Relay 浏览器Automation — CDP over WebSocket 控制无头浏览器
npm install -g openclaw

# 配置文件 ~/.claw-relay/config.yaml
cat > ~/.claw-relay/config.yaml << 'EOF'
server:
  port: 9333
  host: "127.0.0.1"
agents:
  <agent-name>:
    token: "<your-token>"
    scopes: ["read", "interact", "navigate"]
    allowlist: ["*"]
    rateLimit: 60
engine:
  timeout: 30000
  chrome:
    cdpUrl: "ws://127.0.0.1:9222/devtools/browser/<browser-id>"
EOF

# 启动 relay(加上 --no-chrome 表示不自己启动 Chrome,只连接已有的)
claw-relay --config ~/.claw-relay/config.yaml --no-chrome

<browser-id> 从 Chrome 启动时的输出中查找,或者从 ws://127.0.0.1:9222/json 端点获取。

步骤 3:通过 WebSocket 连接并控制浏览器

认证连接:

import websocket, json

ws = websocket.WebSocket()
ws.connect("ws://localhost:9333", timeout=5)
ws.send(json.dumps({
    "type": "auth",
    "token": "<your-token>",
    "agent_id": "hermes"
}))
resp = ws.recv()  # {"type": "result", "action": "auth", "ok": true}

常用指令:

操作 JSON 格式
导航 {"type": "navigate", "url": "https://example.com", "request_id": "1"}
填表 {"type": "fill", "selector": "input[name='x']", "text": "值", "request_id": "2"}
点击 {"type": "click", "selector": "button", "request_id": "3"}
截图 {"type": "screenshot", "request_id": "4"}
批量操作 {"type": "batch", "actions": [...], "request_id": "5"}

示例 — 批量填表提交:

batch_msg = {
    "type": "batch",
    "stopOnError": False,
    "actions": [
        {"type": "fill", "selector": "input[name='custname']", "text": "Test User"},
        {"type": "fill", "selector": "input[name='custtel']", "text": "13800138000"},
        {"type": "click", "selector": "button[type='submit']"}
    ],
    "request_id": "req1"
}
ws.send(json.dumps(batch_msg))

返回格式:

{"type": "result", "action": "fill", "ok": true, "data": "Filled input[name='custname']", "request_id": "req1", "targetId": "tab-1"}

截图返回: base64 编码的 PNG 图片数据(data 字段)

步骤 4:注意事项

  1. V2EX 等站点有 Cloudflare 防护 — 自动化浏览器会被拦截,必须人工完成验证
  2. CSS 选择器要用对 — 优先用 input[name='x'] 这类属性选择器,不要用模糊匹配
  3. batch 操作有原子性stopOnError: true 时遇错即停,false 时继续执行后续
  4. token 安全 — Claw Relay token 相当于浏览器控制权限,不要暴露到前端页面

验证

运行以下测试:

# 连接 + 认证 + 导航 + 截图
ws.connect("ws://localhost:9333")
ws.send(json.dumps({"type": "auth", "token": "<token>", "agent_id": "test"}))
ws.send(json.dumps({"type": "navigate", "url": "https://httpbin.org/forms/post", "request_id": "1"}))
ws.send(json.dumps({"type": "screenshot", "request_id": "2"}))
# 验证 screenshot 返回 base64 数据,navigate 返回 ok:true

已知限制

  • WSL2 下无法控制 Windows Chrome(NAT 隔离问题)
  • Cloudflare、hCaptcha 等防机器人验证无法绕过
  • 部分 SPA 站点需要等待 JavaScript 执行完毕,可能需要额外延时