核心用法 / Core Usage
站点适配器
需要此类任务的 CLI 细节时,按需加载 chrome-use skills get core/site-adapters。普通点击和表单操作已包含在 core 中。
读「站点 X 的结构化数据」,最省的路径是跳过 snapshot + click。
在你 open、翻页、一路点击穿越 GitHub / Reddit / Bilibili 之前,先看有没有现成的
站点适配器——一小段社区写的 JS,在你登录态的标签页里直接打站点自己的 JSON API,
把干净的结构化数据一次交给你。不点击、不爬、不截图。
是什么
站点适配器(site adapter)是社区写的一个 JS 函数:它在你当前登录态的标签页里
直接调用站点自己的 JSON API,返回清洗好的结构化数据。本质上就是打包好的、按站点划分的
eval——只是不用你自己写,也不用摸清每个站点的接口。
因为它跑在你已经登录的那个标签页里、以你的身份发请求,所以像
bilibili/feed、twitter/… 这类需要登录态的信息流也能直接读到——
这正是手拼 URL 或匿名抓取做不到的地方。
eval 打某个站点的内部接口,那站点适配器就是把这段代码
沉淀成命令、由社区维护、按站点归类。你少写一次脏活,别人也复用得到。
怎么用
四个动作:一次性拉取源(update)、看装了哪些(list)、看某个适配器怎么调
(info)、运行它(site <name>/<cmd>)。
$ chrome-use site update # 一次性:拉取社区源、官方源及额外源
$ chrome-use site list # 已装了哪些(github/issues、reddit/search…)
$ chrome-use site info github/issues # 某适配器的参数 + 在哪个域名上跑
$ chrome-use site info github # 整个 pack 的适配器,带参数和用法
$ chrome-use site github/issues owner/repo --json # 运行 → JSON(自动帮你导航过去)
site update:默认从 bb-sites 社区源和 chrome-use-sites 官方源拉取适配器,并同步用户配置的额外源。只需一次;之后 chrome-use 会自动保持同步(见下方「自动触发」)。site list:列出本地已安装的所有<name>/<cmd>,例如github/issues、reddit/search。site info <name>/<cmd>:查一个适配器声明了哪些参数、以及它会在哪个域名上运行——调之前先看这个,就知道该传什么。site info <name>:同上,但列出一个 pack 里的全部适配器,每个都带一行usage,写明必填参数。site <name>/<cmd> [args] --json:真正运行。加--json拿一行可解析的结构化输出。
加了 --json,最后一条命令返回的就是站点自己的数据,已经清洗成可解析的结构(下面为节选、缩进过):
{
"success": true,
"data": {
"domain": "github.com",
"origin": "https://github.com/",
"result": {
"count": 30,
"repo": "epiral/bb-sites",
"state": "open",
"issues": [
{
"number": 85,
"title": "feat(youtube/transcript): migrate to API-based subtitles",
"author": "kerrmoulton",
"state": "open",
"is_pr": true,
"comments": 0,
"labels": [],
"created_at": "2026-06-16T07:54:47Z",
"url": "https://github.com/epiral/bb-sites/pull/85"
}
// … 其余 29 条同构,count 是本次返回的总数
]
}
},
"error": null
}
site info <name>/<cmd> 看它的参数声明和目标域名,
再照着传。这比盲跑一次看报错更省。
参数与导航
适配器的参数按声明顺序用位置参数填入;想按名字覆盖某一个,就用 --key value。
两种写法可以混用:位置参数先占位,--key 再定点覆盖。
# 位置参数按声明顺序填
$ chrome-use site github/issues owner/repo --json
# --key 按名覆盖(顺序无所谓)
$ chrome-use site reddit/search --query "chrome-use" --sort new --json
运行时它会导航到适配器声明的域名——如果你当前标签页已经在那个域名上,就复用当前标签页,
不新开。请求仍发生在你登录态的那个标签页里,所以 bilibili/feed、twitter/…
这类登录才可见的信息流照常返回(为什么能,见上面「是什么」)。
open 到目标站点。site <name>/<cmd> 会自己导航到适配器的域名再执行;
但你得已经登录那个站点,登录态信息流才读得到。
长文本、本地文件、长时间运行
发文章、传视频这类写操作的适配器,也是一条命令跑完:正文从文件读,本地文件直接交给适配器,等上传和发布的时间不再受单次命令约 8 秒的限制。
# 长文本从文件或 stdin 读,不用再写 "$(cat post.md)"
$ chrome-use site csdn/article-publish --title "Hello" --markdown @post.md
$ cat post.md | chrome-use site csdn/article-publish --title "Hello" --markdown @-
# 适配器声明为 "type": "file" 的参数直接给本地路径(site info 里能看到)
$ chrome-use site douyin-creator/video-publish --video ./clip.mp4 --title "Hello"
# 一直跑到上传 / 发布真正完成
$ chrome-use site bilibili-creator/video-publish --title "Hello" --tags a,b --until-done --timeout 10m
# 写适配器:在 @meta.args 里声明文件参数,@meta 里可选 "timeout": 600(秒)
# "video": {"required": true, "type": "file", "input": "input[type=file]"}
# 函数里:把文件放到页面的文件输入框、报告进度、读取本次可用时间
# await args.video.setOn(); args.progress('uploading'); args.budgetMs
--key @path从文件读值,--key @-从 stdin 读,--key-file path是同一件事的显式写法。@name不是文件时保持原样(--user @jack);@x.md、@dir/x这种看起来是路径却不存在的会报错,写错路径不会被当成正文发出去。要传以@开头的字面值,写--key \@text。"type": "file"的参数接收本地路径,由适配器自己调用args.video.setOn()放进页面的文件输入框,不用再单独跑upload,也不用知道选择器。页面只能指定选择器,不能指定路径。- 适配器在页面后台运行,由 chrome-use 轮询,不受扩展 relay 单条命令约 8 秒的限制。
--timeout <300|90s|10m>设定总时长,默认取适配器@meta.timeout,没有则 120 秒。 --until-done:适配器返回status: "incomplete"/"uploading",或者页面跳转中断了这次运行时,自动重跑,直到完成或超时(默认 600 秒)。不加它就把这个状态原样返回,由你再跑一次同样的命令。- 适配器用
args.progress(...)报告的进度会打印到 stderr,--json里在progress字段,另有attempts和elapsedMs。 - 写操作的适配器(发布、删除、评论、关注)用
args.ui让 chrome-use 代为输入(1.5.253 起):args.ui.click(el)、hover、type(el, text, {clear})、press('Enter')、scroll(el | 像素)。用的是真实的 CDP 输入事件(isTrusted: true),鼠标走曲线、按键间隔有变化,先用滚轮把元素滚进可见区,落点在元素内部;元素不见了、没有尺寸或被别的东西挡住时会报错并说明原因。适配器自己的el.click()/dispatchEvent是isTrusted: false,网站能看出来。 - 在
@meta里写"world": "isolated"(1.5.259 起),适配器就在标签页的隔离环境里运行:DOM、cookie、存储和页面共享,但 JS 是自己的一套,页面包装过的querySelector、fetch等一次都不会被调用。只有页面 JS 才有的东西(React fiber 等元素私有属性、应用状态、页面自己带签名的fetch)通过args.page(fn, ...args)拿:fn按源码送到主环境、带 JSON 参数执行,返回 JSON 结果;它看不到适配器的变量,要传选择器而不是元素。旧版 chrome-use 会忽略这个字段、仍在主环境运行:const page = args.page || ((fn, ...a) => fn(...a))。
status: "timeout" 只说明时间到了适配器还在跑,页面里那次运行可能随后完成。重跑发布类命令之前,先看一眼页面实际状态,避免重复发布。
自动触发 —— 看到就用它
你不用记住哪些站点有适配器。chrome-use 会自动保持适配器源同步(首次使用 + 每周),
并且只要你到了一个域名有适配器的页面就主动提示你:open / navigate / snapshot 每次都提示;其他命令(tab new、切换标签页、back / forward、点击跳转、在别人打开的标签页上的第一条命令)只要换了站点也会提示。一直停在同一个站点只提示一次。提示形式:
- stderr 上一行
site adapters for <domain>; --json输出里的siteAdapters: {domain, commands}字段。
$ chrome-use open https://github.com/epiral/bb-sites
# … 页面打开的同时,stderr 冒出一行:
site adapters for github.com — prefer these for structured data:
github/issues, github/pulls, github/repo …
e.g. chrome-use site github/issues <repo> --json
args: chrome-use site info github
site <name>/<cmd>site adapters for <domain> 时,别再 snapshot + click 去读数据——
直接用它点名的 site <name>/<cmd>:更省、更稳,而且已经装好了。你也不需要自己先跑
site update,用它给出的命令即可。
常用的站点还没有适配器
同一个站点操作得多(本次会话 30 条以上,或者用了 3 天以上),却没有适配器时,chrome-use 会在一次响应里加上
siteAdapterSuggestion: {domain, actionsThisSession, daysUsed, message}(stderr 一行 site adapter suggestion: …),
让 AI 问你要不要把反复做的步骤写成适配器。同一站点每次会话最多一次,两周内不再提;本机域名和 IP 不提示。
你同意后,AI 把适配器写进 ~/.chrome-use/my-sites/<name>/<cmd>.js,用
chrome-use site add ~/.chrome-use/my-sites 登记一次,再 site update。
设 AGENT_BROWSER_SITES_NO_SUGGEST=1 关闭这个提示。
添加 OpenCLI 格式的适配器
site add 会自动识别 OpenCLI 格式:OpenCLI 插件仓库(如 chrome-use site add darinouyang/opencli-plugin-shipxy)、zip,或本地目录(比如你已有的 ~/.opencli/clis)。
识别后,这些命令走同一套 OpenCLI 运行时,操作你当前的 chrome-use 会话,site list 里标 (opencli: 来源)。支持 .js,Node 22.13+ 时也支持 .ts;只有 YAML 的插件不支持(OpenCLI 1.8 起自己也不再加载 YAML)。
OpenCLI 适配器是在你电脑上以你的用户权限运行的 Node 代码,不像 chrome-use 适配器那样关在网页里。所以:本地目录直接加;远程仓库会锁定到你确认时的 commit(zip 锁定 SHA-256),在终端里会列出模块让你确认,脚本或 agent 调用时要加 --trust-node-code。
site update 会重新拷贝本地目录,但不会挪动远程的锁定版本;想用新版本就再 site add 一次。同名命令的优先级:我们的适配器 → 你加的 OpenCLI 来源 → OpenCLI 官方包。
OpenCLI:最后的选择
装了 Node.js 20+ 时,site update 会顺带安装 OpenCLI(约 180 个站点、1300 多条命令,固定版本,--ignore-scripts)。
两个适配器库都没有的 name/cmd,会用 OpenCLI 自己的运行时执行,操作的还是你当前的 chrome-use 会话和登录态,比如
chrome-use site hackernews/best --limit 5 --json。site list 里标着 (opencli),site info 能看参数,站点提示里排在最后。
同名时永远用我们自己的(优先级:site add 加的来源 → 官方 chrome-use-sites → 社区 bb-sites → OpenCLI);我们的只读命令运行失败而 OpenCLI 有同名的只读命令时,会自动改用它(写操作不会重试)。AGENT_BROWSER_SITES_NO_OPENCLI=1 关闭。
douyin/delete、douyin/update、twitter/delete、twitter/like、twitter/follow、bilibili/user-videos、bilibili/creator-stats 以前走 OpenCLI,现在移植到 chrome-use-sites 维护(注明出处,Apache-2.0),OpenCLI 不再运行它们;本地缓存里还没有时,第一次使用会先同步。删除、点赞、关注要先打开对应页面,请加 --until-done。
OpenCLI 是第三方代码,chrome-use 不维护,出过坏掉的命令。每次走 OpenCLI 都会在 stderr 打一行 note: … third-party OpenCLI command, not maintained by chrome-use,--json 里有 maintainedBy: "opencli"、readOnly 和 notice。有我们自己的适配器就用我们的;发帖、点赞、关注、删除、发布这类动你真实账号的操作不要依赖 OpenCLI,应该移植进 chrome-use-sites。
站点没登录时
适配器发现站点没登录时,返回 {"loginRequired": true}(error 码随意,可以再带 loginUrl,即站点内的登录页地址)。
error: "login_required" 或 "not_logged_in" 也算。适配器运行失败时,如果它的某个 fetch 拿到 HTTP 401、被重定向到登录页,或者标签页停在了登录页,chrome-use 也按没登录处理。
这时命令失败,stderr 输出 login wall: <host> is not signed in …,--json 里带 loginWall,提示走 auth login --bwu,不再用适配器自己那句「先去登录」。
某个站点第一次遇到时,chrome-use 会问要不要用密码库登录:这次登录、以后这个站点都自动登录、不登录也不再问。终端里直接提问;agent 调用时 loginWall.ask 给出问题和每个选项对应的命令,agent 要转问你,不能替你选。选了 chrome-use auth autologin always <host> 后,会打开 loginUrl,用 vault 里该站点的登录项登录,再把这条命令重跑一次。auth autologin status 查看,auth autologin off <host> 撤销。
写操作只有在适配器自己报了没登录时才重跑;靠 401 或重定向推断出来的失败可能已经执行了一半,留给你去页面确认。
自己写适配器:analyze 和 verify
先在页面上把加载数据的操作做一遍(搜索、滚动、打开列表),再跑 chrome-use site analyze:它列出页面发过的接口请求、页面里嵌着的初始数据(__NEXT_DATA__、__INITIAL_STATE__ 等)和检测到的反爬厂商,并推荐取数方式。
优先顺序:公开 API,网站自己的 JSON 接口(在页面里带 cookie 调用),页面嵌入的数据,最后才是 DOM;越往后越容易坏。
写好后用 chrome-use site verify <name>/<cmd> [参数] --write-fixture 记下一次正确结果的结构;之后 site verify 发现字段消失、类型变了或列表变空就失败(退出码 1)。fixture 只存结构,不存数据。
site <name>/<cmd>
可能提示「未安装」。这时手动跑一次 site update,再重跑那条命令即可。
什么时候用它 vs extract --schema vs snapshot
同一页数据往往有多条路。站点适配器是已知站点结构化数据的首选;没有合适适配器时, 再往下退。下面这张表帮你对号入座。
| 你的情况 | 用什么 | 为什么 |
|---|---|---|
| 已知站点的结构化数据(GitHub issues、Reddit/HN 搜索、B 站 / Twitter 信息流),尤其登录态之后 | chrome-use site <name>/<cmd> |
直接打站点 JSON API、以你身份运行,跳过 snapshot + click,最省最稳 |
| 任意页面的结构化数据,没有社区适配器——表格、搜索结果、信息流行、仪表盘 | extract --schema '{rows,fields}' |
给个形状,一次调用出干净 JSON,不用自己写 eval、也不倒整页 HTML |
要给模型做推理、或需要拿 @ref 去交互 |
snapshot -i --json |
结构化快照带稳定 ref,既能读也能驱动后续 click / type |
| 需要自定义形状、逻辑较特殊的一次性抽取 | eval --stdin |
在页面 MAIN world 里直接写 JS,最灵活(适配器就是它的沉淀版) |
extract --schema;再不行才回到常规的
snapshot / eval 手动循环。数据抽取的全景见 提取数据。
来源与许可
适配器默认来自 bb-sites 社区源和
chrome-use-sites 官方源。
chrome-use 负责在运行时拉取并执行它们——本仓库不打包、不重分发任何适配器代码,
site update 每次从上游获取最新版本。
site list 反映的是你本地这一次同步到的版本。
下一步
站点适配器是数据抽取里最省的一档;配合下面这些手段覆盖其余场景。