- method_l_shape: OK 候选尺度 ±0.0375 精修(步长 0.0125 + ±6px 窗口), GT live_165204 Δ 179→176(真人 177),离线 9/10 保持 - 插桩 JSON.stringify 捕获 SDK 日志明文;指针 probe 排除 coalesced/pressure - 拖动不跟手指标作废:post_pos 晚于 SDK 重置滑块,鼠标事件流始终完整 - 剩余 VerifyErr = 候选整体选错(视觉确证),方向:多候选质量评估 - docs: experiments/solution/retrospective 同步收尾
58 lines
1.8 KiB
Markdown
58 lines
1.8 KiB
Markdown
# 经验:CDP 9222 连接与 browser-use 基础操作
|
||
|
||
> 场景:需要对用户已登录的真实 Chrome(远程调试端口 9222)做自动化操作。
|
||
|
||
## 连接检查
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:9222/json/version # 通了即可用
|
||
curl -s http://127.0.0.1:9222/json # 列出页面 target
|
||
```
|
||
|
||
## browser-use 调用模式
|
||
|
||
CLI 名为 `browser-use`,用 heredoc 传 Python 代码,helpers 已预导入:
|
||
|
||
```bash
|
||
browser-use <<'PY'
|
||
for t in list_tabs(): # 列出所有页面 tab
|
||
print(t["targetId"], t["url"][:80])
|
||
PY
|
||
```
|
||
|
||
## 关键 API
|
||
|
||
| API | 用途 |
|
||
| --- | --- |
|
||
| `list_tabs()` | 列出页面 tab,返回完整 targetId |
|
||
| `switch_tab(targetId)` | attach 到指定 tab(不改变 Chrome 可见 tab);**必须传完整 targetId**,8 位前缀会报 `No target with given id found` |
|
||
| `activate_tab(targetId)` | 把 tab 切到前台(用户可见) |
|
||
| `js(expression)` | 在当前页面执行 JS,自动 await Promise |
|
||
| `capture_screenshot(path)` | 截图保存到本地文件 |
|
||
| `click_at_xy(x, y)` | 视口坐标点击(CDP 鼠标事件,穿透 iframe/shadow DOM) |
|
||
| `cdp("Domain.method", ...)` | 任意 CDP 协议调用 |
|
||
| `wait_for_load(15)` | 等待导航完成 |
|
||
|
||
## 坑:js() 顶层 let/const 会跨调用残留
|
||
|
||
`Runtime.evaluate` 在页面全局作用域执行,顶层 `let out = []` 会留下全局词法绑定,
|
||
下次调用再写 `let out` 直接 `SyntaxError: Identifier 'out' has already been declared`。
|
||
|
||
**解法:所有多行 JS 一律包 IIFE:**
|
||
|
||
```python
|
||
r = js("""
|
||
(() => {
|
||
let out = [];
|
||
...
|
||
return out.join('\\n');
|
||
})()
|
||
""")
|
||
```
|
||
|
||
## 注意
|
||
|
||
- 每个 `browser-use <<'PY'` 是独立 Python 进程,Python 变量不跨调用保留;
|
||
页面状态(DOM、JS 全局变量)跨调用保留。
|
||
- CDP target 顺序 ≠ Chrome 可见 tab 标签页顺序,用 `list_tabs()` 认 URL。
|