mcpField
Q
qiaomu-opencli-browser

qiaomu-opencli-browser

github.com/joeseesunAgent 工作流9971.1k 次安装29 周前更新
代码仓库

关于 qiaomu-opencli-browser

qiaomu-opencli-browser 是供 AI Agent 使用的浏览器自动化技能,通过 OpenCLI 命令行控制 Chrome。它可检查页面结构、与元素交互、发现网络 API,并将浏览过程整理为可复用的 CLI 适配器。

主要功能

  1. 01通过命令行控制 Chrome
  2. 02结构化 DOM 检查
  3. 03页面交互与数据提取
  4. 04网络 API 发现
  5. 05创建可复用 CLI 适配器

适用场景

  1. 01自动执行浏览器工作流
  2. 02提取网页数据
  3. 03探索 API 并构建 CLI 适配器

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/joeseesun/qiaomu-opencli-skills --skill qiaomu-opencli-browser

安装后在 Claude Code 中输入/qiaomu-opencli-browser确认已加载。

详细介绍

OpenCLI Browser — 面向 AI Agent 的浏览器自动化

通过 CLI 逐步控制 Chrome。复用现有登录会话,无需密码。

前置条件

opencli doctor    # Verify extension + daemon connectivity

要求:Chrome 正在运行,并已安装 OpenCLI Browser Bridge 扩展。

关键规则

  1. 始终使用 state 检查页面,绝不要使用 screenshot — state 会返回带有 [N] 元素索引的结构化 DOM,速度快且不消耗 token。screenshot 需要进行视觉处理,速度较慢。只有用户明确要求保存视觉图像时,才使用 screenshot。
  2. 始终使用 click/type/select 进行交互,绝不要使用 eval 来点击或输入 — eval "el.click()" 会绕过 scrollIntoView 和 CDP 点击流程,导致屏幕外元素操作失败。使用 state 查找 [N] 索引,然后执行 click <N>。
  3. 使用 get value 而非截图验证输入 — 执行 type 后,运行 get value <index> 进行确认。
  4. 每次页面变化后都运行 state — 执行 open、click(针对链接)或 scroll 后,始终运行 state,查看新元素及其索引。绝不要猜测索引。
  5. 尽可能使用 && 链接命令 — 将 open + state、多个 type 调用以及 type + get value 合并到单个 && 链中。每次工具调用都有开销;链接命令可以减少开销。
  6. eval 仅供只读使用 — eval 只能用于提取数据(JSON.stringify(...)),绝不能用于点击、输入或导航。始终将其包装在 IIFE 中以避免变量冲突:eval "(function(){ const x = ...; return JSON.stringify(x); })()"。
  7. 尽量减少工具调用总数 — 操作前规划好步骤。完成一项任务通常需要 3-5 次工具调用,而非 15-20 次。将 open + state 合并为一次调用。将 type + type + click 合并为一次调用。只有需要发现新索引时,才单独运行 state。
  8. 优先使用 network 发现 API — 大多数网站都有 JSON API。基于 API 的适配器比 DOM 抓取更可靠。

命令开销指南

开销命令使用时机
免费且即时state、get *、eval、network、scroll、keys默认使用这些命令
免费但会更改页面open、click、type、select、back交互后运行 state
开销高(视觉 token)screenshot仅当用户需要保存图像时使用

操作链接规则

命令可以通过 && 链接。浏览器通过守护进程保持运行,因此可以安全地链接命令。

尽可能始终链接命令 — 工具调用越少,完成越快:

# GOOD: open + inspect in one call (saves 1 round trip)
opencli browser open https://example.com && opencli browser state

# GOOD: fill form in one call (saves 2 round trips)
opencli browser type 3 "hello" && opencli browser type 4 "world" && opencli browser click 7

# GOOD: type + verify in one call
opencli browser type 5 "[email protected]" && opencli browser get value 5

# GOOD: click + wait + state in one call (for page-changing clicks)
opencli browser click 12 && opencli browser wait time 1 && opencli browser state

# BAD: separate calls for each action (wasteful)
opencli browser type 3 "hello"    # Don't do this
opencli browser type 4 "world"    # when you can chain
opencli browser click 7            # all three together

会更改页面的命令 — 始终放在命令链末尾(后续命令会看到过期的索引):

  • open <url>、back、click <link/button that navigates>

规则:已知索引时进行链接。需要先发现索引时,单独运行 state。

核心工作流

  1. 导航:opencli browser open <url>
  2. 检查:opencli browser state → 带有 [N] 索引的元素
  3. 交互:使用索引 — click、type、select、keys
  4. 等待(如有需要):opencli browser wait selector ".loaded" 或 wait text "Success"
  5. 验证:opencli browser state 或 opencli browser get value <N>
  6. 重复:浏览器会在各命令之间保持打开
  7. 保存:将 TS 适配器写入 ~/.opencli/clis/<site>/<command>.ts

命令

导航
opencli browser open <url>              # Open URL (page-changing)
opencli browser back                    # Go back (page-changing)
opencli browser scroll down             # Scroll (up/down, --amount N)
opencli browser scroll up --amount 1000
检查(免费且即时)
opencli browser state                   # Structured DOM with [N] indices — PRIMARY tool
opencli browser screenshot [path.png]   # Save visual to file — ONLY for user deliverables
获取(免费且即时)
opencli browser get title               # Page title
opencli browser get url                 # Current URL
opencli browser get text <index>        # Element text content
opencli browser get value <index>       # Input/textarea value (use to verify after type)
opencli browser get html                # Full page HTML
opencli browser get html --selector "h1" # Scoped HTML
opencli browser get attributes <index>  # Element attributes
交互
opencli browser click <index>           # Click element [N]
opencli browser type <index> "text"     # Type into element [N]
opencli browser select <index> "option" # Select dropdown
opencli browser keys "Enter"            # Press key (Enter, Escape, Tab, Control+a)
等待

有三种方式 — 根据情况选择合适的方式:

opencli browser wait time 3                       # Wait N seconds (fixed delay)
opencli browser wait selector ".loaded"            # Wait until element appears in DOM
opencli browser wait selector ".spinner" --timeout 5000  # With timeout (default 30s)
opencli browser wait text "Success"                # Wait until text appears on page

何时等待:在 SPA 上执行 open 后、执行会触发异步加载的 click 后,以及对动态渲染内容执行 eval 前。

提取(免费且即时,只读)

eval 只能用于读取数据。绝不能用它来点击、输入或导航。

opencli browser eval "document.title"
opencli browser eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"

# IMPORTANT: wrap complex logic in IIFE to avoid "already declared" errors
opencli browser eval "(function(){ const items = [...document.querySelectorAll('.item')]; return JSON.stringify(items.map(e => e.textContent)); })()"

选择器安全性:始终使用备用选择器 — querySelector 未匹配时会返回 null:

# BAD: crashes if selector misses
opencli browser eval "document.querySelector('.title').textContent"

# GOOD: fallback with || or ?.
opencli browser eval "(document.querySelector('.title') || document.querySelector('h1') || {textContent:''}).textContent"
opencli browser eval "document.querySelector('.title')?.textContent ?? 'not found'"
网络(API 发现)
opencli browser network                  # Show captured API requests (auto-captured since open)
opencli browser network --detail 3       # Show full response body of request #3
opencli browser network --all            # Include static resources
沉淀(保存为 CLI)
opencli browser init hn/top              # Generate adapter scaffold at ~/.opencli/clis/hn/top.ts
opencli browser verify hn/top            # Test the adapter (adds --limit 3 only if `limit` arg is defined)
  • init 会从当前活动的浏览器会话中自动检测域名(无需指定)
  • init 会创建文件,并根据当前页面填充 site、name、domain 和 columns
  • verify 会端到端运行适配器并打印输出;如果适配器中没有 limit 参数,就不会传递 --limit 3
会话
opencli browser close                   # Close automation window

示例:提取 HN 故事

opencli browser open https://news.ycombinator.com
opencli browser state                   # See [1] a "Story 1", [2] a "Story 2"...
opencli browser 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                   # See [3] input "Customer Name", [4] input "Telephone"
opencli browser type 3 "OpenCLI" && opencli browser type 4 "555-0100"
opencli browser get value 3             # Verify: "OpenCLI"
opencli browser close

保存为可复用 CLI — 完整工作流

分步沉淀流程:
# 1. Explore the website
opencli browser open https://news.ycombinator.com
opencli browser state                          # Understand DOM structure

# 2. Discover APIs (crucial for high-quality adapters)
opencli browser eval "fetch('/api/...').then(r=>r.json())"   # Trigger API calls
opencli browser network                        # See captured API requests
opencli browser network --detail 0             # Inspect response body

# 3. Generate scaffold
opencli browser init hn/top                    # Creates ~/.opencli/clis/hn/top.ts

# 4. Edit the adapter (fill in func logic)
# - If API found: use fetch() directly (Strategy.PUBLIC or COOKIE)
# - If no API: use page.evaluate() for DOM extraction (Strategy.UI)

# 5. Verify
opencli browser verify hn/top                  # Runs the adapter and shows output

# 6. If verify fails, edit and retry
# 7. Close when done
opencli browser close
适配器示例:
// ~/.opencli/clis/hn/top.ts
import { cli, Strategy } from '@jackwener/opencli/registry';

cli({
  site: 'hn',
  name: 'top',
  description: 'Top Hacker News stories',
  domain: 'news.ycombinator.com',
  strategy: Strategy.PUBLIC,
  browser: false,
  args: [{ name: 'limit', type: 'int', default: 5 }],
  columns: ['rank', 'title', 'score', 'url'],
  func: async (_page, kwargs) => {
    const limit = Math.min(Math.max(1, kwargs.limit ?? 5), 50);
    const resp = await fetch('https://hacker-news.firebaseio.com/v0/topstories.json');
    const ids = await resp.json();
    return Promise.all(
      ids.slice(0, limit).map(async (id: number, i: number) => {
        const item = await (await fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)).json();
        return { rank: i + 1, title: item.title, score: item.score, url: item.url ?? '' };
      })
    );
  },
});

保存到 ~/.opencli/clis/<site>/<command>.ts → 即可立即通过 opencli <site> <command> 使用。

策略指南
策略适用场景browser:
Strategy.PUBLIC公共 API,无需身份验证false
Strategy.COOKIE需要登录 Cookietrue
Strategy.UI直接操作 DOMtrue

始终优先使用 API,而非 UI — 如果你在浏览过程中发现了 API,请直接使用 fetch()。

提示

  1. 始终先运行 state — 切勿猜测元素索引,务必先检查
  2. 会话会持续保留 — 浏览器会在命令之间保持打开,无需重新打开
  3. 使用 eval 提取数据 — eval "JSON.stringify(...)" 比多次调用 get 更快
  4. 使用 network 查找 API — JSON API 比 DOM 抓取更可靠
  5. 别名:opencli op 是 opencli browser 的简写

常见问题

  1. 自动化中 form.submit() 会失败 — 不要使用 form.submit() 或 eval 提交表单。请直接导航到搜索 URL:

    # BAD: form.submit() often silently fails
    opencli browser eval "document.querySelector('form').submit()"
    # GOOD: construct the URL and navigate
    opencli browser open "https://github.com/search?q=opencli&type=repositories"
    
  2. GitHub DOM 经常变化 — 如果有 data-testid 属性,请优先使用;它们比类名或标签结构更稳定。

  3. SPA 页面提取前需要 wait — 在单页应用中执行 open 或 click 后,DOM 不会立即就绪。执行 eval 前,务必使用 wait selector 或 wait text。

  4. 点击前先运行 state — 运行 opencli browser state,检查可用的交互元素及其索引。切勿凭记忆猜测索引。

  5. evaluate 在浏览器上下文中运行 — 适配器中的 page.evaluate() 会在浏览器内执行。Node.js API(fs、path、process)不可用。网络调用请使用 fetch(),页面数据请使用 DOM API。

  6. page.evaluate 中的反引号会破坏 JSON 存储 — 编写需要以 JSON 格式存储或传输的适配器时,请避免在 page.evaluate 中使用模板字面量。请使用字符串拼接或函数形式的 evaluate:

    // BAD: template literal backticks break when adapter is in JSON
    page.evaluate(`document.querySelector("${selector}")`)
    // GOOD: function-style evaluate
    page.evaluate((sel) => document.querySelector(sel), selector)
    

故障排除

错误解决方法
"Browser not connected"运行 opencli doctor
"attach failed: chrome-extension://"暂时禁用 1Password
未找到元素opencli browser scroll down && opencli browser state
页面更改后索引失效再次运行 opencli browser state 获取最新索引

评论

支持 Markdown