用你的真实浏览器——会话、登录态、Cookie 全部保留
面向命令行和 AI 的浏览器会话操作工具。通过 Chrome/Firefox 扩展 + Native Messaging,将你的真实浏览器页面结构化为 XML/JSON 输出,并支持点击、输入等交互操作。
核心特性:
- 有状态会话 — 登录态、Cookie、跳转历史全部保留
- 体积极小 — CLI 二进制约 2 MB,内存占用很低,易于安装和使用
- 结构化 XML 输出 — token 消耗低,AI/Agent 直接可读
- 短 ID 操作 — 无需 CSS 选择器,稳定可靠
- 高仿真交互 — 模拟真实鼠标轨迹和键盘输入,绕过反爬检测
- 性能优异 — 读操作命中内存缓存,DOM 分段采集不阻塞渲染,结构化计算在 CLI 侧完成
- 声明式插件 — TOML 规则文件,复用自动化操作
| browser-cli | opencli | Playwright / Selenium | curl / requests | |
|---|---|---|---|---|
| 浏览器实例 | 真实浏览器(Chrome/Firefox) | 真实浏览器(Chrome) | 新建独立实例 | 无浏览器 |
| 会话保留 | ✅ 登录态 / Cookie | ✅ 复用 Chrome 会话 | ❌ 每次重置 | ❌ |
| 支持范围 | 任意页面 | 50+ 预置站点 | 任意页面 | 任意 URL |
| 交互方式 | 通用(click / type) | 站点专属命令 | 编程 API | HTTP 请求 |
| 反爬检测 | 真实指纹 | 防检测增强 | 易被识别 | 易被识别 |
| 页面输出 | 精简 XML/JSON | 确定性结果 JSON | HTML / DOM | HTML |
| AI/Agent 消费 | 低 token,结构化 | 低 token,结构化 JSON | 高 token,原始 | 高 token |
Chrome:
在 Chrome 打开 chrome://extensions,开启「开发者模式」,点击「加载已解压的扩展程序」,选择 extension/dist/chrome/ 目录(开发模式);或从 Releases 下载 .zip、解压后以同样方式加载。
记录扩展 ID(形如 abcdefghijklmnopabcdefghijklmnop),后续注册时需要用到。
Firefox:
从 Releases 下载 .xpi 文件,在 Firefox 打开 about:addons,点击齿轮图标 → 「从文件安装附加组件」,选择 .xpi 文件完成安装。
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/4fuu/open-browser-cli/main/install.sh | shHomebrew:
brew tap 4fuu/open-browser-cli https://github.com/4fuu/open-browser-cli
brew install browser-cliWindows(Scoop):
scoop bucket add open-browser-cli https://github.com/4fuu/open-browser-cli
scoop install browser-cliWindows(PowerShell 脚本)
irm https://raw.githubusercontent.com/4fuu/open-browser-cli/main/install.ps1 | iexChrome:
browser-cli setup --extension-id <扩展ID>Firefox:
browser-cli setup --browser firefox注册文件写入后,重启浏览器 使配置生效。如需卸载:
browser-cli teardown --browser chrome # 或 --browser firefox# 打开网页,创建会话并返回当前页面结构
browser-cli open https://example.com
# 查看页面结构
browser-cli page s1234567890
# 点击元素(支持 e1 / 1 / 文本查询)
browser-cli click s1234567890 "Sign In"
# 向输入框输入文本
browser-cli type s1234567890 "Search" "hello world"
# 等待页面稳定,或等待指定文本出现
browser-cli wait s1234567890
browser-cli wait s1234567890 --for "Continue"
# 查看被截断的长文本 / 分页块
browser-cli text s1234567890 t1
browser-cli block s1234567890 b1 --source-page 1 --all
# 关闭会话
browser-cli close s1234567890browser-cli open <url> [--wait <毫秒>] [--quiet] [--json]
browser-cli list [--json]
browser-cli close <session-id> [--json]
browser-cli close --all [--json]
browser-cli --version
browser-cli page <session-id> [-p <页码>] [--next] [--prev] [--fresh] [--json] [--verbose]
browser-cli click <session-id> <目标> [-p <页码>] [--new-session] [--fresh] [--quiet] [--json]
browser-cli type <session-id> <目标> <文本> [-p <页码>] [--fresh] [--quiet] [--json]
browser-cli search <session-id> <关键词> [--fresh] [--json] [--verbose]
browser-cli text <session-id> <文本ID|数字> [-p <页码>] [--fresh] [--json]
browser-cli block <session-id> <块ID|数字> [--source-page <页码>] [(-p <块页码>)|--all] [--fresh] [--json] [--verbose]
browser-cli view <session-id> <目标> [-p <页码>] [--fresh] [--json] [--verbose]
browser-cli wait <session-id> [--for <文本>] [--timeout <毫秒>] [--quiet] [--json]
browser-cli screenshot <session-id> [--output <路径>] [--full-page] [--quality <0-100>] [--json]
browser-cli download <session-id> <元素ID|URL> [--output <路径>] [--json]
browser-cli plugin list [--json]
browser-cli plugin run <名称> <session-id> [--json]
browser-cli setup [--browser chrome|firefox] [--extension-id <ID>]
browser-cli teardown [--browser chrome|firefox]
<page url="https://example.com" title="Example" current="1" total="3">
<heading level="1">Welcome</heading>
<text id="t1">这是一段较长的文本[...truncated]</text>
<link id="e1" href="/login">Sign In</link>
<button id="e2">Get Started</button>
<input id="e3" type="text" placeholder="Search..."/>
<checkbox id="e4" checked/>
<list id="b1" truncated="true" shown="18" total_items="42" current="1" total="3">
<item>Item one</item>
<item>Item two</item>
</list>
</page>e1,e2, ... — 交互元素 ID,用于click/type;参数支持e1或1t1,t2, ... — 被截断的长文本 ID,用text命令查看完整内容;参数支持t1或1b1,b2, ... — 被分页的长list/table块 ID,用block命令继续查看后续分页;参数支持b1或1--next/--prev按当前滚动位置相对翻页--fresh跳过缓存,强制从浏览器获取最新快照--version显示构建时注入的版本号;若未注入则显示unknownopen默认会在创建会话后直接输出当前页;用--quiet只看会话信息,用--wait 0可跳过打开后的稳定等待open/close/list/search/wait/plugin/view全部支持--jsonpage/search/block/view支持--verbose:主要用于拿完整 JSON 细节;不带时,--json默认返回更紧凑的数据click/type的<目标>既可以是带前缀 ID(如e1)、数字 ID(如1对应e1),也可以是当前页交互元素的文本查询;查询会匹配按钮文本、链接文本、输入框 placeholder/value 等click/type默认会输出更新后的整页 XML;可用--quiet只看成功结果,用--json获取结构化摘要wait默认等待页面稳定并返回最新页面;--for <文本>会轮询最新快照,直到页面里出现匹配该文本的元素screenshot可保存当前页面视口截图;指定--quality时会输出 JPEG,否则默认 PNG;--full-page当前会提示并回退为视口截图download可下载浏览器当前会话可访问的资源;目标既可以是页面元素 ID(自动取其href/src),也可以是直接 URLsearch在 XML/纯文本模式下仍返回page、tag、上下文摘要,以及命中交互元素时的element_id;在--json下默认返回紧凑结果,--verbose才返回完整匹配结构- 长文本截断会明确显示为
[...truncated] - 超长
list/table会在页面中先显示首段,并带上块级分页属性;分页按渲染后的 XML 行数预算切分,而不是按条目数量硬切;可用browser-cli block <session-id> <块ID或数字> --source-page <页码> -p <块页码>读取单页,或用--all一次展开整个块 view会返回某个元素、长文本或长块的聚焦视图;目标支持e3/3/t1/b1/ 文本查询view命中列表或表格中的元素时,默认只返回包含该目标的单条item/row;加--verbose才返回完整列表/表格上下文click --new-session仅对带href的链接生效;CLI 会把链接解析成绝对 URL,并直接创建一个新的 session,原页面保持不变
规则文件(TOML)放在 ~/.config/browser-cli/plugins/:
name = "skip-cookie-banner"
description = "自动关闭 cookie 弹窗"
match = "*.example.com/*"
trigger = "on_load"
[[steps]]
wait = "Accept"
timeout = 3000
action = "click"browser-cli plugin list --json返回结构化插件列表browser-cli plugin run <名称> <session-id> --json返回执行摘要(总步数、完成/跳过/失败数量、页面是否更新)
- Relay 监听固定端口
127.0.0.1:12899,同一时间只运行一个实例 - 元素 ID(
e1,e2, ...)每次page后重新编号,操作前需先获取当前页面 page --fresh、search --fresh、text --fresh、block --fresh、view --fresh,以及click/type的--fresh,都用于动态页面需要绕过缓存的场景wait默认就会在成功后返回最新页面;自动化链路里如果只需要成功/超时结果,用--quietclick --new-session是显式行为,不会自动套用到普通点击;如果目标元素不是链接,命令会直接报错
CLI(Rust):
cargo build --release
# 产物:target/release/browser-cli浏览器扩展:
cd extension
npm install
npm run build # 产物:extension/dist/chrome/ 和 extension/dist/firefox/
npm run pack # 打包为 extension/dist/browser-cli-extension.zip 和 browser-cli-extension.xpibrowser-cli 操作的是你本机正在运行的真实浏览器。会话由用户(Agent)显式打开和关闭,只要会话存活,登录状态、Cookie、表单输入、跳转历史全部保留。
页面以精简 XML 返回,只保留可交互元素和可见文本,过滤所有无关噪声,token 消耗低,语义清晰,AI/Agent 直接可读。
每次 page 后交互元素获得短 ID(e1, e2, ...),直接用 ID 操作,无需构造易碎的 CSS 选择器或 XPath。点击模拟真实鼠标轨迹,输入逐字符派发并带随机延迟,通过原型 setter 绕过 React/Vue 等框架的 value 检测。
page/search/text 等只读命令优先命中 Relay 内存缓存,无需每次往返浏览器;只有 click/type 等写操作才触发浏览器执行并更新快照。
Content Script 采用分段推送(每 100 个节点、8ms 间隔),不阻塞页面渲染,繁重的结构化计算全部在 CLI 侧完成。重复操作可用 TOML 插件描述,一次编写,所有会话自动触发。
欢迎提交 Issue 和 Pull Request。贡献前请阅读 CONTRIBUTING.md。