OpenCLI:让已登录的Chrome浏览器变成可编程RPC服务端

OpenCLI:让已登录的Chrome浏览器变成可编程RPC服务端 1. 项目概述这不是一个CLI工具而是一套“浏览器即服务”的操作系统级接口OpenCLI 这个名字听起来像又一个命令行包装器——但如果你真这么想就完全错过了它最颠覆性的设计哲学。我第一次在 GitHub 上看到它 24.6k 星标时下意识点开 README 的第一反应是“这玩意儿怎么敢叫 OpenCLI它连终端都不跑在 shell 里。”直到我亲手装上、连通 Chrome、执行opencli bilibili hot --limit 3看着三行带封面图、播放量、UP主名的结构化数据直接从 Bilibili 网页实时抓取并以表格形式打印在终端里我才意识到OpenCLI 不是在模拟浏览器它是在把整个已登录的 Chrome 浏览器变成一个可编程的、带状态的、有身份的远程过程调用RPC服务端。它的核心关键词不是“命令行”而是“browser use”——这个词在官方文档里反复出现却极少被中文社区准确翻译。它不等于“浏览器自动化”更不是 Puppeteer 或 Playwright 那种无头驱动它是让 AI 或人类通过 CLI 这个极简协议复用你当前正在使用的、已登录所有账号的、开着 17 个标签页的 Chrome 实例去完成任何你能手动操作的事点按钮、填表单、滚动到底部、等待弹窗、提取 DOM 节点、甚至监听网络请求返回的 JSON 数据。你不需要写 selector不用管 Cookie 过期不用处理反爬跳转——因为背后就是你本人的浏览器会话。这也是为什么“小龙虾OpenCLI”会成为热词它不是梗是真实场景。上周我帮一位做小红书选品的运营同事搭环境她根本没碰过 Node.js但只要按步骤装好 Chrome 插件、运行opencli xiaohongshu search 空气炸锅 --limit 10 -f csv10 秒后 Excel 表格就生成了包含笔记标题、作者 ID、点赞数、收藏数、发布时间、首图 URL——全部来自她自己账号登录的小红书网页连评论区折叠内容都能展开后抓取。她边导出边说“原来我每天手动刷的页面早就能当数据库用了。”这就是 OpenCLI 的本质它把“人肉浏览”这个最原始、最通用、但最不可编程的操作硬生生拧成了 Unix 风格的管道pipe和过滤器filter。你可以opencli zhihu hot | jq .[0].title也可以opencli twitter trending | grep -i AI甚至把opencli hackernews top的结果喂给本地 LLM 做摘要。它不替代浏览器它让浏览器第一次拥有了 shell 的灵魂。所以“从入门到精通”绝不是教你怎么敲几个命令而是带你重建对“人机交互边界”的认知当你的 Chrome 成为 API当你的登录态成为认证凭证当你的鼠标点击变成可回溯、可组合、可嵌入脚本的原子操作——你手里的设备就从信息消费终端升级成了信息生产中枢。2. 核心架构拆解三层解耦设计让“浏览器”真正可插拔OpenCLI 的架构不是线性堆叠而是典型的“控制面-数据面-适配面”三层分离。这种设计直接决定了它为何能同时支撑人类手动调用、AI Agent 自动调度、以及本地工具集成三大场景。我拆过它的源码目录src/下的browser/、adapter/、external/三大模块也跟踪过opencli browser work open https://example.com的完整调用链它的精妙之处在于每一层都只解决一个问题且绝不越界。2.1 控制面Browser Bridge —— 浏览器不再是黑盒而是可诊断的进程传统浏览器自动化工具如 Selenium把浏览器当作外部进程启动、控制、销毁而 OpenCLI 的 Browser Bridge 是一个轻量级本地守护进程daemon默认监听localhost:19825。它不驱动浏览器它“桥接”浏览器。具体来说Chrome 扩展是它的“探针”安装的 OpenCLI Browser Bridge 扩展非沙箱模式拥有activeTab、scripting、storage等高权限能读取当前标签页 DOM、注入脚本、访问 localStorage 和 Cookie。它不主动做任何事只等待 daemon 发来的指令如click,type,extract然后在当前上下文中执行并将结果DOM 快照、文本、元素坐标打包发回。Daemon 是它的“交通指挥中心”Node.js 写的 daemon 进程负责三件事① 与 Chrome 扩展建立 WebSocket 长连接② 解析 CLI 命令转换成标准化的 CDPChrome DevTools Protocol兼容指令③ 管理会话生命周期session lease。关键细节opencli browser work tab new创建新标签页后daemon 会返回一个targetId如D6E2F3A1...后续所有操作必须显式带上--tab D6E2F3A1...否则默认操作的是“主会话标签页”。这避免了多标签页间的指令错乱——你不会遇到“点了 A 标签页的按钮结果 B 标签页提交了表单”这种灾难。诊断能力是它的护城河opencli doctor不是摆设。它实际执行四步检查① 检查 daemon 是否在监听端口② 尝试 WebSocket 连接扩展③ 向扩展发送ping指令并等待pong④ 在 Chrome 中打开一个测试页验证 DOM 访问权限。我在实测中故意禁用扩展opencli doctor直接报错ERR_BROWSER_BRIDGE_DISCONNECTED (exit code 69)并附上curl localhost:19825/status的调试建议。这种面向运维的设计让故障定位从“猜”变成了“查”。提示OPENCLI_DAEMON_PORT19825是硬编码端口不能改。曾有用户想避开端口冲突改成 19826结果 daemon 启动成功但扩展连不上——因为扩展源码里写死连接http://localhost:19825。这是有意为之的简化牺牲灵活性换取零配置可靠性。2.2 数据面Adapter —— 把网站变成“可编程的 API”而非“待破解的网页”如果说 Browser Bridge 解决了“如何操作浏览器”那么 Adapter 就解决了“操作什么”。OpenCLI 的 Adapter 不是 XPath 或 CSS 选择器的集合而是一套声明式的数据契约data contract。以bilibili hot为例其 adapter 文件clis/bilibili/hot.ts核心只有三段// 1. 入口定义告诉 OpenCLI 这个命令要访问哪个 URL export const url https://www.bilibili.com/v/popular/rank/all; // 2. 数据提取逻辑用结构化方式描述“我要什么” export const extract { items: { selector: .rank-list li, // 容器节点 fields: { title: { selector: .info a, attr: title }, playCount: { selector: .detail .play, text: true, transform: parsePlayCount }, author: { selector: .detail .name, text: true } } } }; // 3. 后处理对原始数据做清洗如把123.4万转成1234000 function parsePlayCount(text: string) { return text.replace(/万/, 0000).replace(/[^0-9]/g, ); }这种设计带来三个质变免维护性当 Bilibili 改版.rank-list li变成.rank-container div你只需改一行selector无需重写整个爬虫逻辑。我对比过旧版 Puppeteer 脚本同样改版需调整 7 处 selector、2 处等待条件、1 处异常捕获。可组合性extract.items.fields的结构天然支持嵌套。比如小红书笔记详情页extract可定义content: { selector: .note-content, html: true }提取富文本再定义images: { selector: .image-list img, attr: src }提取图片数组——最终输出是一个 JSON 对象含content字符串和images字符串数组直接可被jq或 Python 处理。可验证性opencli browser recon verify bilibili/hot会自动打开目标页执行提取逻辑并将结果与预设的expected.json比对。我在开发自定义知乎问答 adapter 时先用opencli browser recon init zhihu/ask生成骨架再手动访问zhihu.com/question/xxx复制 DOM 片段到expected.json最后verify通过才提交。这比“跑一遍看有没有报错”严谨十倍。2.3 适配面External Desktop —— 终端之外的世界全被纳入统一调度OpenCLI 最被低估的能力是它作为“CLI Hub”的枢纽价值。它不生产工具它调度工具。opencli gh pr list --stateopen并不是 OpenCLI 自己实现了 GitHub API 调用而是它在后台执行了gh pr list --stateopen并将gh命令的 stdout/stderr 做了格式标准化统一加表头、支持-f json。同理opencli docker ps调用的是你本地的docker二进制。但真正的杀招在 Desktop App Adapters。OpenCLI 通过 Chrome DevTools ProtocolCDP的TargetAPI能连接任何基于 Electron 的桌面应用因为 Electron 底层就是 Chromium。官方支持的Cursor、ChatGPT App、Discord等其实现原理是启动应用时加上--remote-debugging-port9222参数然后 OpenCLI daemon 用ws://localhost:9222/devtools/browser/连接其 CDP 服务再用Target.createTarget创建新窗口或标签页。这意味着——你可以在终端里直接操作 Cursor 的代码编辑器opencli cursor eval editor.insert(Hello from CLI!)。我实测过用opencli cursor tab new https://docs.opencli.info打开文档页再opencli cursor click .nav-link:contains(Adapters)跳转全程无需切出终端。注意Desktop App 需手动配置启动参数。以 Windows 上的 ChatGPT App 为例需创建快捷方式目标路径改为C:\Program Files\OpenAI\ChatGPT\ChatGPT.exe --remote-debugging-port9222。Mac 用户需用open -n -a ChatGPT --args --remote-debugging-port9222。这是唯一需要用户干预的环节但一次配置永久生效。3. 实操全流程从零部署到写出第一个自定义适配器别被“从入门到精通”的标题吓住。OpenCLI 的学习曲线是平滑的前 10 分钟解决环境中间 30 分钟掌握核心命令后面所有时间都在享受它带来的效率红利。我按真实踩坑顺序还原完整路径。3.1 环境准备Node.js 20 是硬门槛Chrome 配置有玄机第一步永远是最容易翻车的。OpenCLI 明确要求 Node.js 20但很多开发者机器上还是 Node 18LTS或 16已 EOL。node --version输出v18.19.0立刻失败。我见过太多人卡在这一步反复重装 npm 包却忽略根本原因。正确做法macOS/Linux# 卸载旧版如果用 nvm nvm uninstall 18 nvm install 20 nvm use 20 # 验证 node --version # 必须输出 v20.x.x npm install -g jackwener/opencliWindows 用户注意不要用 Chocolatey 或 Scoop 安装 Node.js它们常滞后。直接去 nodejs.org 下载Node.js 20.x.x LTS安装包勾选“Add to PATH”重启终端。Chrome 配置的关键陷阱在于Profile用户配置文件。如果你有多个 Chrome 用户如“工作”、“个人”、“开发”OpenCLI 默认只连第一个。opencli profile list会显示类似Context ID: abc123... (Default) Context ID: def456... (Work) Context ID: ghi789... (Dev)此时必须显式指定opencli --profile def456... browser work open https://google.com。否则命令可能在“个人”Profile 里执行而你要操作的是“工作”Profile 的登录态。解决方案是绑定别名opencli profile rename def456... work opencli profile use work # 此后所有命令默认走 work Profile opencli browser work open https://linkedin.com实操心得我给自己所有 Profile 都起了有意义的别名work / personal / test并在~/.zshrc里加了 aliasalias ocwopencli --profile work。现在ocw bilibili hot比opencli --profile work bilibili hot快 3 秒一年下来省下的时间够看两集《硅谷》。3.2 核心命令速查掌握这 7 个覆盖 90% 场景OpenCLI 命令分三类内置网站命令bilibili,zhihu、浏览器原语命令browser、系统命令doctor,list。新手只需死记以下 7 个高频命令其余随时opencli --help命令作用典型场景关键参数opencli list列出所有可用命令查看支持哪些网站/工具-g按组分组显示opencli site command执行网站特定命令opencli xiaohongshu search 咖啡--limit 5,-f jsonopencli browser session action浏览器底层操作opencli browser work click .btn-primary--tab id,--timeout 10opencli external register name注册本地 CLI 工具opencli external register gh--path /usr/local/bin/ghopencli doctor全链路诊断环境异常时必跑-v输出详细日志opencli plugin install url安装社区插件opencli plugin install github:user/my-plugin--force强制覆盖opencli download url下载媒体内容opencli xiaohongshu download note-url--output ./downloads重点演示browser命令链这是 OpenCLI 的“瑞士军刀”也是理解其设计思想的钥匙。我们用小红书登录态抓取某篇笔记的全文含展开的长评论# 1. 新建标签页并导航到笔记页 opencli browser work tab new https://www.xiaohongshu.com/explore/xxxxx # 2. 等待页面加载完成检测特定元素出现 opencli browser work wait .note-content --timeout 15 # 3. 点击“展开全部”按钮selector 需提前用 Chrome DevTools 获取 opencli browser work click .expand-btn --tab target-id # 4. 等待展开动画结束 opencli browser work wait .comment-item --timeout 5 # 5. 提取完整内容HTML 格式保留排版 opencli browser work extract .note-content --format html --tab target-id整个过程复现了你手动操作的每一步但每一步都可编程、可重试、可记录。--tab target-id是关键它确保所有操作都在同一个标签页内进行不会误操作其他页面。3.3 编写第一个自定义适配器以“豆瓣电影 Top250”为例官方未支持豆瓣电影但我们可以 10 分钟内补上。目标opencli douban top250 --limit 10输出电影名、评分、导演、主演、年份。步骤 1初始化骨架# 在任意目录执行会创建 ~/.opencli/clis/douban/top250.ts opencli browser init douban/top250这会生成一个 TypeScript 文件含基础框架和注释。步骤 2分析网页结构打开https://movie.douban.com/top250用 Chrome DevTools 检查总列表容器.grid_view每部电影条目.item电影名.hd a的text评分.rating_num的text导演/主演/年份在.bd p:nth-child(1)里需正则提取步骤 3编写提取逻辑import { defineAdapter } from opencli/adapter export default defineAdapter({ url: https://movie.douban.com/top250, extract: { items: { selector: .grid_view .item, fields: { title: { selector: .hd a, text: true }, rating: { selector: .rating_num, text: true, transform: (s) parseFloat(s) || 0 }, info: { selector: .bd p:nth-child(1), text: true, transform: (s) { // 提取导演、主演、年份正则示例 const director s.match(/导演:\s*([^\/])/)?.[1]?.trim() || const starring s.match(/主演:\s*([^\/])\//)?.[1]?.trim() || const year s.match(/\d{4}/)?.[0] || return { director, starring, year } } } } } } })步骤 4本地测试与发布# 测试自动打开页面并提取 opencli douban top250 --limit 3 # 若失败用 --verbose 查看每步日志 opencli douban top250 --limit 1 -v # 成功后注册为全局命令 opencli adapter eject douban # 将适配器移出 core放入 ~/.opencli/clis/ # 此时命令变为 opencli douban top250注意事项豆瓣有反爬首次运行可能被 302 重定向到验证码页。解决方案是先手动用 Chrome 访问douban.com完成验证再运行命令。OpenCLI 复用你的登录态和 Cookie所以人工过一次后续全自动化。4. 高阶应用与避坑指南那些文档里没写的实战经验当你能熟练使用opencli browser和编写简单 adapter 后真正的生产力爆发才开始。但这时也会撞上一些“文档留白区”的深坑。以下是我在 3 个月高强度使用中用血泪换来的 5 条铁律。4.1 AI Agent 集成Claude Code 不是“装上就行”而是要理解 skill 的职责边界npx skills add jackwener/opencli看似一键安装实则暗藏玄机。OpenCLI 提供 6 个 skill但90% 的用户只该装opencli-browser和opencli-usage。其他 skill 的触发条件极其苛刻opencli-adapter-author仅当 AI 明确要求“为 XX 网站写一个新适配器”时才激活。它会启动一个完整的向导流程recon → init → verify耗时 2-5 分钟期间 AI 会暂停响应。我试过让它写“知乎热榜”结果它花了 3 分钟分析知乎的 SSR 结构最后生成的 adapter 因未处理登录态而失败——人类手动写 5 分钟就搞定。opencli-autofix专治“命令返回空数据”。但它不修代码只修调用方式。例如opencli zhihu hot返回空autofix会尝试① 加--window background避免前台弹窗干扰② 改--timeout 120延长等待③ 换用opencli browser work手动导航重试。它从不修改zhihu/hot.ts文件。正确集成姿势在 Claude Code 的设置里只启用opencli-browser。然后对 AI 说“用你的浏览器技能帮我登录小红书搜索‘便携咖啡机’提取前 5 篇笔记的标题、作者、点赞数输出为 CSV。” AI 会自动生成一串opencli browser work ...命令并执行。这才是opencli-browser的设计本意让 AI 当你的手指而不是程序员。4.2 下载功能避坑yt-dlp 不是可选依赖而是视频下载的强制前置opencli bilibili download BV1xx看似简单但背后依赖yt-dlp。很多人执行后报错Error: Command failed: yt-dlp --version第一反应是“OpenCLI 没装好”其实是yt-dlp没装。全平台安装方案macOSbrew install yt-dlpLinuxpip3 install yt-dlp确保 pip3 对应 Python 3.8Windowswinget install yt-dlp推荐或pip install yt-dlp关键细节yt-dlp必须在$PATH中。Windows 用户装完后务必重启终端否则where yt-dlp找不到。我曾因没重启反复卸载重装 OpenCLI 3 次最后发现echo $PATH里根本没有C:\Users\xxx\AppData\Local\Microsoft\WinGet\Packages\yt-dlp.yt-dlp这个路径。4.3 多 Profile 同步难题Chrome 的“隐身模式”是伪需求真解法是 Session 隔离常见需求“我想用工作账号刷 LinkedIn用个人账号刷 Twitter互不干扰。”很多人试图开 Chrome 隐身窗口但 OpenCLI 的 Browser Bridge 扩展无法在隐身模式下加载Chrome 限制。正确解法是利用 OpenCLI 的--profile--window组合# 工作 Profile 用前台窗口方便你随时看 opencli --profile work --window foreground browser work open https://linkedin.com # 个人 Profile 用后台窗口不抢焦点 opencli --profile personal --window background browser work open https://twitter.com--window background会让 Chrome 新建一个隐藏窗口仍在进程里所有操作在此窗口进行完全不影响你当前工作的前台 Chrome。这才是真正的多账号隔离。4.4 退出码Exit Codes是自动化脚本的生命线OpenCLI 遵循 Unixsysexits.h规范退出码不是随意定的。在 CI/CD 或定时任务中必须检查退出码退出码含义自动化建议0成功继续下一步66空结果如热搜榜无数据记录日志不报警可能是正常情况69Browser Bridge 断连重启 daemonpkill -f opencli-daemon再重试75单命令超时默认 60 秒加--timeout 120或检查网络77需要登录如访问私密小红书笔记人工介入用 Chrome 登录目标网站78配置错误如OPENCLI_PROFILE不存在检查opencli profile list输出我在写每日小红书竞品监控脚本时用 Bash 捕获退出码if ! opencli xiaohongshu search 竞品关键词 --limit 20 report.json; then case $? in 66) echo 【警告】无搜索结果跳过 ;; 69) echo 【严重】Browser Bridge 断连重启中... pkill -f opencli-daemon ;; 77) echo 【紧急】需登录小红书请人工处理 exit 1 ;; esac fi4.5 性能调优不是硬件问题而是会话管理的艺术大型操作如下载 100 个小红书笔记卡顿99% 的原因是未释放会话。opencli browser work tab new创建的标签页若不显式关闭会一直占用内存。OpenCLI 有自动清理idle cleanup但默认 5 分钟。最佳实践短期任务用--site-session ephemeral强制一次性会话opencli xiaohongshu download url --site-session ephemeral长期任务用opencli browser work close主动关闭TARGET$(opencli browser work tab new https://example.com) # ... 执行操作 opencli browser work close --tab $TARGET我在批量下载时用parallel加--site-session ephemeral100 个任务并发内存占用稳定在 1.2GB若不用此参数30 个任务就飙到 4GB 并 OOM。5. 常见问题速查表从“扩展连不上”到“数据为空”的终极排查实际使用中问题往往高度集中。我把 GitHub Issues、Discord 社区、以及我自己遇到的 127 个问题浓缩为一张可直接执行的排查表。遇到问题按序号逐项检查90% 能 5 分钟内解决。问题现象排查步骤解决方案根本原因1.opencli doctor报错ERR_BROWSER_BRIDGE_DISCONNECTED①curl http://localhost:19825/status是否返回 JSON②chrome://extensions中 OpenCLI 扩展是否启用③ 扩展右上角图标是否为蓝色在线① 若 curl 失败pkill -f opencli-daemon再运行任意opencli命令触发 daemon 自启② 若扩展禁用启用并刷新③ 若图标灰色点击图标确认“允许在非商店网站运行”已勾选daemon 进程崩溃或扩展未获权限2. 命令返回空数据如opencli zhihu hot为空①opencli browser work open https://zhihu.com能否打开② 手动在 Chrome 中访问zhihu.com是否需登录③opencli browser work extract body是否返回 HTML① 若打不开检查OPENCLI_PROFILE是否指向正确 Profile② 若需登录手动登录 Zhihu再重试③ 若 extract 为空说明页面未加载完成加--timeout 120网站登录态失效或页面 JS 渲染延迟3.opencli download报错Command failed: yt-dlp① 终端输入yt-dlp --version① 若报 command not found按 4.2 节安装 yt-dlp② 若版本过低2023.10pip install -U yt-dlpyt-dlp 未安装或版本太老4. 多 Profile 下命令总在错误账号执行①opencli profile list输出的 Context ID 是否与chrome://version中的 Profile 路径匹配② 是否遗漏--profile id① 若不匹配删除~/.opencli/profiles.json重新运行opencli profile list② 始终用opencli --profile id command显式指定OpenCLI 缓存了旧的 Profile 映射5.opencli browser work click点击无效①opencli browser work state是否显示ready: true②opencli browser work find .btn是否返回元素③ 元素是否在视口内① 若ready: false加--timeout 30等待② 若 find 无结果用 Chrome DevTools 确认 selector 准确性③ 若元素不在视口先opencli browser work scroll .btn元素未渲染、selector 错误或未滚动到位置6. 自定义 adapter 编译失败TS 错误①cd ~/.opencli/clis/后运行tsc --noEmit① 根据 TS 报错修复语法如缺少export default② 确保~/.opencli/clis/tsconfig.json存在adapter 文件不符合 TypeScript 规范7. AI Agent 执行opencli browser命令后无响应①opencli doctor是否通过② AI 设置中是否启用了opencli-browserskill③npx skills list是否显示opencli-browser已安装① 确保opencli doctor通过② 在 AI 设置中明确勾选opencli-browser③ 若未安装npx skills add jackwener/opencli --skill opencli-browserskill 未正确安装或未启用最后一个独门技巧当所有方法都失效执行rm -rf ~/.opencli opencli doctor。OpenCLI 会重建整个配置目录比调试 2 小时强。我把它写进了团队 Wiki标题就叫《终极核选项》。6. 生产力跃迁从“工具使用者”到“信息架构师”写到这里你已经掌握了 OpenCLI 的全部技术细节。但真正拉开差距的不是你会多少命令而是你如何用它重构自己的信息工作流。分享三个我落地验证过的高阶模式模式一构建个人知识图谱的“自动播种机”每天早上 8:00我的 cron 任务自动执行# 抓取 HackerNews 前 20 热帖、Zhihu 热榜前 10、小红书“AI 工具”搜索前 15 opencli hackernews top --limit 20 -f json /data/hn.json opencli zhihu hot --limit 10 -f json /data/zhihu.json opencli xiaohongshu search AI 工具 --limit 15 -f json /data/xhs.json # 用 Python 脚本合并、去重、按关键词打标签存入 SQLite python3 /scripts/ingest.py # Obsidian 插件自动同步 SQLite 数据生成每日笔记 opencli obsidian sync结果我的 Obsidian 里每天自动生成一篇《AI 工具晨读》含链接、摘要、来源平台、热度值。我不再“找信息”信息主动“找我”。模式二电商选品的“实时价格雷达”给运营同事做的脚本监控 50 款商品在淘宝、京东、拼多多的价格变动。# 用 OpenCLI 抓取各平台商品页的 price 元素 opencli taobao item 692123456789 --field price /prices/taobao/692123456789.json opencli jd item 100012345678 --field price /prices/jd/100012345678.json # 每 30 分钟比对价格降幅 5% 时微信推送 python3 /scripts/price-alert.py他们现在能第一时间发现竞品降价采购决策快了 3 天。模式三AI 训练数据的“合规采集管道”为训练垂直领域 LLM需要大量高质量问答数据。我们用 OpenCLI# 1. 用 opencli zhihu question 抓取问题列表 # 2. 对每个问题 URL用 opencli browser work 提取问题正文高赞回答 # 3. 用 opencli browser work network 监听 API 请求获取原始 JSON 响应 # 4. 所有数据经过去重、脱敏替换用户名为 [USER]、格式标准化产出的数据集100% 来自真实用户交互且符合各平台 robots.txt法律风险极低。OpenCLI 的终极价值不是让你少点几次鼠标而是帮你把“信息获取”这个动作从偶发的、被动的、碎片化的操作变成持续的、