其他
用 OpenCLI 在 Chrome 现有登录态下让 AI…
当需要在不提供 LLM API key、复用 Chrome 登录会话的前提下,让 AI/CLI 代理导航、点击、输入、等待、抽取网页数据或生成站点 CLI 时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 39/100 ×0.15
适用场景
用 OpenCLI 在 Chrome 现特定
解决思路
- 运行 `opencli doctor` 验证扩展 + daemon 连通性;确保 Chrome 正在运行且已安装 OpenCLI Browser Bridge 扩展。
- 用 `opencli browser open <url>` 导航。
- 用 `opencli browser state` 获取结构化 DOM 和 `[N]` 元素索引;始终先用 `state`,绝不猜测元素索引。
- 绝不用 `screenshot` 检查页面;`state` 即时且零 token。仅当用户明确要求保存可视图片时使用 `opencli browser screenshot [path.png]`。
- 交互只用 `click`/`type`/`select`;绝不用 `eval` 去点击或输入,因为 `eval` 中调用 `el.click()` 会绕过 scrollIntoView 和 CDP click pipeline,导致离屏元素失败。先用 `state` 找到 `[N]`,再执行 `click <N>`。
- 输入后用 `get value <index>` 验证,不要用截图验证。
- 每次页面变化后运行 `state`:`open`、会导航的 `click`、`scroll` 后都运行 `opencli browser state`,查看新元素和索引,绝不猜索引。
- 积极用 `&&` 串联命令:把 `open + state`、多个 `type`、`type + get value` 合并到单次调用,减少 tool call 开销。
- `eval` 只读:只用于数据抽取,如 `JSON.stringify(...)`;绝不用于点击、输入或导航。
- 复杂 `eval` 总是用 IIFE 包裹避免变量冲突:在 `eval` 中执行 `(function(){ const x = ...; return JSON.stringify(x); })()`。
- 最小化总 tool calls:行动前先规划序列;良好任务完成用 3-5 次 tool call,而不是 15-20 次。
- 把 `open + state` 合成一次调用;把 `type + type + click` 合成一次调用;只有需要发现新索引时才单独运行 `state`。
- 优先用 `network` 发现 API;多数站点有 JSON API,基于 API 的 adapter 比 DOM scraping 更可靠。
- 命令成本:`state`、`get *`、`eval`、`network`、`scroll`、`keys` 免费即时,作为默认使用。
- `open`、`click`、`type`、`select`、`back` 免费但会改变页面;交互后运行 `state`。
- `screenshot` 昂贵且消耗 vision token;仅当用户需要保存图片时使用。
- 命令可用 `&&` 串联;浏览器通过 daemon 持久化,因此串联安全。
- 可能时总是串联,减少调用次数:例如 `opencli browser open https://example.com && opencli browser state` 节省 1 次往返。
- 表单一次填:`opencli browser type 3 'hello' && opencli browser type 4 'world' && opencli browser click 7`,节省 2 次往返。
- 输入并验证一次做:`opencli browser type 5 'test@example.com' && opencli browser get value 5`。
- 会改变页面的点击用:`opencli browser click 12 && opencli browser wait time 1 && opencli browser state`。
- 不要每个动作分开调用,例如不要连续单独执行 `type 3`、`type 4`、`click 7`,能在已知索引时串联就串联。
- 页面改变命令总是放在 `&&` 链最后:`open <url>`、`back`、会导航的 `click <link/button>`;因为后续命令会看到旧索引。
- 串联规则:已经知道索引时串联;需要先发现索引时单独运行 `state`。
- 核心工作流:1 导航 `opencli browser open <url>`;2 检查 `opencli browser state` 得到带 `[N]` 索引的元素;3 用索引交互 `click`、`type`、`select`、`keys`;4 如需要等待 `wait selector '.loaded'` 或 `wait text 'Success'`;5 验证 `state` 或 `get value <N>`;6 重复,浏览器在命令间保持打开;7 保存 TS adapter 到 `~/.opencli/clis/<site>/<command>.ts`。
- 导航命令:`opencli browser open <url>`;`opencli browser back`;`opencli browser scroll down`;`opencli browser scroll up --amount 1000`。
- 检查命令:`opencli browser state` 是 PRIMARY 工具;`opencli browser screenshot [path.png]` 仅用于用户交付物。
- 获取命令:`opencli browser get title`、`get url`、`get text <index>`、`get value <index>`(type 后验证)、`get html`、`get html --selector 'h1'`、`get attributes <index>`。
- 交互命令:`opencli browser click <index>`、`type <index> 'text'`、`select <index> 'option'`、`keys 'Enter'`(Enter、Escape、Tab、Control+a)。
- Wait 三种变体:`wait time 3` 固定延迟;`wait selector '.loaded'` 等元素进入 DOM;`wait selector '.spinner' --timeout 5000` 带超时(默认 30s);`wait text 'Success'` 等文本出现。
- 何时 wait:SPA 的 `open` 后、触发异步加载的 `click` 后、对动态渲染内容执行 `eval` 前。
- Extract 用 `eval` 只读读取数据:例如在 `eval` 中返回 `document.title`;在 `eval` 中执行 `JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))`。
- Selector 安全:始终用 fallback selector,因为 `querySelector` 未命中返回 `null`;坏例子是在 `eval` 中直接取 `document.querySelector('.title').textContent` 会崩溃;好例子用 `||` 或 `?.`:`(document.querySelector('.title') || document.querySelector('h1') || {textContent:''}).textContent`、`document.querySelector('.title')?.textContent ?? 'not found'`。
- Network:`opencli browser network` 显示自 `open` 后自动捕获的 API 请求;`network --detail 3` 查看请求 #3 的完整响应体;`network --all` 包含静态资源。
- 沉淀为 CLI:`opencli browser init hn/top` 在 `~/.opencli/clis/hn/top.ts` 生成 adapter scaffold;`opencli browser verify hn/top` 测试 adapter(仅当 adapter 定义了 `limit` arg 时才加 `--limit 3`)。
- `init` 自动从当前浏览器 session 检测域名,无需指定;它创建文件并从当前页面填充 `site`、`name`、`domain`、`columns`。
- `verify` 端到端运行 adapter 并打印输出;如果 adapter 无 `limit` arg,则不会传 `--limit 3`。
- 会话命令:`opencli browser close` 关闭自动化窗口。
- 示例:抽取 HN stories:`opencli browser open https://news.ycombinator.com`;`opencli browser state` 看到 `[1] a Story 1`、`[2] a Story 2` 等;在 `eval` 中执行 `JSON.stringify([...document.querySelectorAll('.titleline a')].slice(0,5).map(a => ({title: a.textContent, url: a.href})))`;`opencli browser close`。
- 示例:填表:`opencli browser open https://httpbin.org/forms/post`;`opencli browser state` 看到 `[3] input Customer Name`、`[4] input Telephone`;`opencli browser type 3 'OpenCLI' && opencli browser type 4 '555-0100'`;`opencli browser get value 3` 验证为 `OpenCLI`;`opencli browser close`。
- 保存为可复用 CLI 的完整流程:1 用 `open` + `state` 探索网站并理解 DOM 结构;2 发现 API:在 `eval` 中执行 `fetch('/api/...').then(r=>r.json())` 触发 API 调用,`network` 查看捕获请求,`network --detail 0` 查看响应体;3 生成 scaffold:`init hn/top` 创建 `~/.opencli/clis/hn/top.ts`;4 编辑 adapter 填入 `func` 逻辑:有 API 就用 `fetch()`(`Strategy.PUBLIC` 或 `Strategy.COOKIE`),无 API 就用 `page.evaluate()` 做 DOM 抽取(`Strategy.UI`);5 用 `verify hn/top` 运行并显示输出;6 如果 verify 失败,编辑并重试;7 完成后 `close`。
- Adapter 定义通常包含 `site`、`name`、`description`、`domain`、`strategy`、`browser`、`args`、`columns`、`func`;保存到 `~/.opencli/clis/<site>/<command>.ts` 后立即可用为 `opencli <site> <command>`。
- 示例 adapter:`hn/top` 使用 `Strategy.PUBLIC`、`browser: false`、`args: [{ name: 'limit', type: 'int', default: 5 }]`、`columns: ['rank','title','score','url']`;`func` 中把 limit 限制在 1..50,请求 `https://hacker-news.firebaseio.com/v0/topstories.json`,再对前 N 个 id 请求 `https://hacker-news.firebaseio.com/v0/item/${id}.json` 并返回 `rank/title/score/url`。
- Strategy 指南:`Strategy.PUBLIC` 用于公共 API、无 auth,`browser: false`;`Strategy.COOKIE` 需要登录 cookies,`browser: true`;`Strategy.UI` 直接 DOM 交互,`browser: true`。
- 始终优先 API 而非 UI:如果浏览过程中发现 API,就直接用 `fetch()`。
- Tips:总是先 `state`,绝不猜元素索引。
- Tips:session 持久化,浏览器在命令间保持打开,无需重新 open。
- Tips:用 `eval` 中执行 `JSON.stringify(...)` 做数据抽取比多次 `get` 调用更快。
- Tips:用 `network` 找 API;JSON API 比 DOM scraping 更可靠。
- Tips:`opencli op` 是 `opencli browser` 的简写别名。
- 陷阱:`form.submit()` 在自动化中会失败;不要用 `form.submit()` 或 `eval` 提交表单,改为直接构造 URL 并导航,例如 `opencli browser open 'https://github.com/search?q=opencli&type=repositories'`(坏做法:在 `eval` 中执行 `document.querySelector('form').submit()`)。
- 陷阱:GitHub DOM 频繁变化;优先使用 `data-testid` 属性,它比 class 名或标签结构更稳定。
- 陷阱:SPA 页面抽取前需要 `wait`;`open` 或 `click` 后 DOM 不一定立即就绪;在 `eval` 前总是 `wait selector` 或 `wait text`。
- 陷阱:点击前用 `state` 检查可用交互元素和索引,绝不凭记忆猜索引。
- 陷阱:adapter 中的 `page.evaluate()` 在浏览器上下文运行;Node.js API(`fs`、`path`、`process`)不可用;用 `fetch()` 做网络调用,用 DOM API 取页面数据。
- 陷阱:`page.evaluate` 中的反引号会破坏 JSON 存储;当 adapter 会以 JSON 存储/传输时,避免在 `page.evaluate` 里使用 template literals(反引号字符串),改用字符串拼接或 function-style evaluate,例如用 `page.evaluate((sel) => document.querySelector(sel), selector)`。
- 排障:错误 `Browser not connected` 时运行 `opencli doctor`。
- 排障:错误 `attach failed: chrome-extension://` 时临时禁用 1Password。
- 排障:Element not found 时运行 `opencli browser scroll down && opencli browser state`。
- 排障:页面变化后索引过期时重新运行 `opencli browser state` 获取新索引。
适用边界 · 注意事项
- 未安装或无法运行 OpenCLI Browser Bridge 扩展、Chrome 或 opencli daemon,且 `opencli doctor` 无法连通时。
- 需要非 Chrome 浏览器、无头环境或不允许复用/自动化现有浏览器登录态时。
- 只需调用公开静态 API 或抓取静态 HTML、不需要浏览器动态渲染和登录会话时,应优先用普通 HTTP 客户端。