核心用法 / Core Usage

交互操作

读到页面之后,就该动手了。这一页覆盖驱动真实浏览器的全部交互动词—— 点击、输入、勾选、下拉、上传、滚动、拖拽。 大多数命令的第一个参数是 snapshot -i 拿到的 @ref(例如 @e42);先定位元素, 再用这里的命令操作它。

点击与指针

最常用的一组动词,都作用在一个 @ref 上。click 会自动把元素滚动进视口, 若坐标点击被遮挡,会回退到 DOM 的 .click()

点击 / 悬停 / 聚焦
$ chrome-use click @e1                   # 点击
$ chrome-use click @e1 --new-tab         # 在新标签页打开链接,而不是当前页导航
$ chrome-use dblclick @e1                # 双击
$ chrome-use hover @e1                   # 悬停
$ chrome-use focus @e1                   # 聚焦(键盘输入前常用)
✅ 点击成功却「没反应」?
典型场景:一个 autocomplete/菜单的 <li> 在输入框失焦时就关掉了。 换成 DOM 派发的点击再试一次: AGENT_BROWSER_CLICK_MODE=dom chrome-use click @e1, 或直接用 eval 在页面里选中那一项。

输入文本

fill 先清空再输入,type 在现有内容后追加。默认走 insertText(快),但很多带联想的字段只对真实按键有反应——这时加 --key-events

fill / type
$ chrome-use fill @e2 "hello"            # 清空后输入
$ chrome-use type @e2 " world"          # 不清空,直接追加
$ chrome-use type @e2 "hello" --clear   # type 也能先清空字段再输入
$ chrome-use type @e2 "hello" --delay 80  # 每个按键之间间隔 80ms

# 真实按键(非 insertText)——用于只认按键事件的联想/组合框,
# 例如输入邮编后自动补全市区(Google Places 一类)
$ chrome-use type @e5 "201-0001" --key-events

# 真实按键并回车提交候选(--enter 隐含 --key-events)——
# 用于异步联想 / 标签控件,例如掘金「添加标签」
$ chrome-use type @e6 "ChatGPT" --enter
ℹ️ --key-events 还是 --enter?
如果只想确认一个标签、且单纯输入不弹下拉,用 --enter 一步到位。 如果你更想从候选列表里挑一个,先 type … --key-events 触发下拉, 再 snapshot -i 找到候选并 click @ref
✅ --clear 与 --delay
--cleartype 也能先清空字段(不用再切回 fill); --delay <ms> 在按键之间插入固定间隔,模拟更慢、更真实的打字节奏。 两者都是各自独立的 flag,不会污染实际打进去的文本。

键盘

press 在当前焦点上按一个键(按下+抬起),也支持组合键。 keydown/keyup 把按下和抬起拆开,成对使用可以实现「按住」。

press / keydown / keyup
$ chrome-use press Enter                 # 在当前焦点按一个键
$ chrome-use press Control+a             # 组合键
$ chrome-use keydown d                   # 按住某键不放(不自动抬起)
$ chrome-use keyup d                     # 抬起——成对用来「按住移动」
                                       # 游戏里:keydown d; sleep; keyup d
ℹ️ 游戏 / Canvas 里更精确的按住
对 canvas / WebGL 应用,用 press d --hold 800 更好——按住时长在守护进程里计时, 比 keydown + shell sleep + keyup 每轮少 ~250ms 抖动。详见 Canvas 与游戏

勾选、选择与下拉

复选框用 check/uncheck。下拉:原生 <select>自定义组合框(react-select / ARIA 等)都可以用 select—— 自 v1.5.72 起,select 遇到非原生控件会自动走 portal-aware 逻辑(开控件→等选项→按可见文本点); pick 是同一能力的显式别名。

check / select / pick
$ chrome-use check @e3                   # 勾选复选框
$ chrome-use uncheck @e3                 # 取消勾选

$ chrome-use select @e4 "Pageview"       # 原生 <select> 或自定义组合框(v1.5.72+)
$ chrome-use select @e4 "a" "b"          # 多选

# 任意组合框:打开它、等菜单出现(含 portal 渲染)、按可见文本匹配、
# 触发正确事件;若选项始终不出现会「报错」(不会静默无操作)
$ chrome-use pick @e4 --option "Europe"
✅ v1.5.72:原生命令扛 shadow-DOM 重站(#105)
以前 select 对自定义下拉会「返回 ✓ 却没变化」(静默假成功)——现已修复: 非原生控件走 portal-aware 逻辑,选项始终不出现时明确报错并列出可见选项,不再静默。 fill 同样加固:能填进模块作用域内的 Monaco 编辑器window.monaco 拿不到时用合成 paste)、 以及 @ref 落在包裹元素上的受控输入(自动下钻到内部 editable)。像 Cloudflare Zaraz 这类 react-select + Monaco + shadow-DOM 的后台,现在原生 select/fill 就能驱动,不用再手搓 eval

上传文件

upload 给文件 <input> 或拖拽/粘贴式的编辑器(如 X 的输入框)投喂文件。 它在扩展中继模式下也能工作。

upload
$ chrome-use upload @e5 file1.pdf        # 上传文件
ℹ️ 为什么中继模式也能上传
chrome.debugger 禁止 setFileInputFiles,所以文件字节会被流式送进页面、 在页面里重建成一个 File(按 native-messaging 的 1 MiB 上限分块传输)。 因此文件 <input> 和 drop/paste 编辑器都能收到。

滚动

scroll 按方向滚动页面;scrollintoview 把某个元素滚进视口。 对跨源 iframe(支付 / 结算 / KYC 组件)里的内容,普通页面滚动够不着,用 --at x,y 在像素点上滚滚轮,或 --frame n 指定帧。

scroll / scrollintoview
$ chrome-use scroll down 500              # 滚动页面(up/down/left/right)
$ chrome-use scroll down 700 --at 640,400  # 在某像素点滚滚轮——能滚到普通页面
                                        # 滚不到的跨源 iframe(Stripe/结算/KYC)
$ chrome-use scroll down 700 --frame 2    # 滚 `chrome-use frames` 里的第 2 帧
$ chrome-use scrollintoview @e1           # 把元素滚进视口

拖拽与滑块验证码

drag 既能在两个 ref 之间拖放,也能把一个手柄按像素偏移拖动(滑块 / canvas)。 对无人值守登录常见的网易易盾滑块验证码,用 solve-slider 自动过。

drag / solve-slider
$ chrome-use drag @e1 @e2                # 拖放
$ chrome-use drag @e1 60                 # 把手柄拖 +60px(滑块/canvas);`+60,-3` 表示 dx,dy
$ chrome-use solve-slider                # 自动解页面上的网易易盾滑块验证码
$ chrome-use solve-slider 5              # ……最多重试 5 次(每次失败会刷新拼图)
ℹ️ solve-slider 是怎么过的
它按 URL 抓取验证码自己的背景图 + 拼图切片(不截图),离线用边缘 + 掩码互相关定位缺口, 再用拟人化、自校准的闭环轨迹把手柄拖进缺口——正是这段人类般的运动通过了易盾的行为检测。 float(内嵌)和 popup(模态,如知乎)两种模式都支持,在触发滑块的提交之后立即运行即可。 这个拖拽会强制启用 humanize 轨迹,不受全局 AGENT_BROWSER_HUMANIZE 影响。
⚠️ 还没覆盖的验证码
易盾的增强版滑块(图标形状拼块 + 干扰项)和点选(按顺序点击) 是更难的挑战,目前尚未处理。

跨源 iframe:始终按 ref 操作

内嵌的支付 / 结算 / KYC 组件(Google Payments、Stripe 等)是跨进程的 out-of-process iframe。 用 ref 驱动它们,永远不要靠截图。 snapshot -i 会穿透这些 iframe,按 @ref 列出里面的元素(含输入框的值); get text --all-frames 读它们的文本。拿到 ref 后照常操作即可。

在 iframe 里按 ref 操作
# snapshot -i 列出跨源 iframe 内的元素,然后:
$ chrome-use click @e
$ chrome-use type @e "…"
$ chrome-use hover @e
$ chrome-use dblclick @e
$ chrome-use drag @a @b

# 帧内的邮编/联想框——用真实按键:
$ chrome-use type @e "201-0001" --key-events
✅ 为什么按 ref 而不是坐标
在扩展中继模式下,这些操作是通过 DOM 在元素自己的帧里派发的, 所以能精准命中正确标签页里的正确元素。而坐标点击/滚动可能漂移到当前前台的其它标签页上—— 所以优先用 ref。帧内需要滚动到下方内容时,用 scroll down N --at x,y(帧上的一个像素点)或 --frame n
⚠️ find 够不到闭合 shadow root 或跨源 iframe
find/选择器匹配的是页面 DOM(querySelectorAll),所以对这两类元素会报 「Element not found」——即便 snapshot -i 能列出它们(它走 CDP 可访问性树,能穿透两者)、 get text 能读到。这时请用快照里的 @ref 定位,而不是 findbox @ref 可给出坐标兜底。另外,先核对准确的标签文案再断定它「不存在」: LinkedIn 的「Save」按钮实际标注为 收藏 而非 保存snapshot -i 一直显示着 button "收藏" [ref=eN],直接 click @eN 即可。

接下来

交互只是核心循环的一环,搭配这几页一起看: