开始 / Getting Started
核心循环
驱动浏览器完成一件事,节奏几乎永远是这四步:打开页面 → 看清页面上有什么 → 对着快照给出的 @ref 动手 → 页面一变就重新快照。
把这个循环跑顺,再理解 @ref 何时失效、何时自愈,你就掌握了 chrome-use 九成的日常用法。
四步循环
每一步都对着上一步的结果做决定:snapshot -i 给你一份只含可交互元素的结构化视图,
每个元素带一个短 @ref;你拿 ref 去 click / type;页面一旦变化,就再快照一次拿到新的 ref。
$ chrome-use open <url> # 1. 打开一个页面
$ chrome-use snapshot -i # 2. 看清页面上有什么(只列可交互元素)
$ chrome-use click @e3 # 3. 对着快照给出的 ref 动手
$ chrome-use snapshot -i # 4. 页面一变,就重新快照
浏览器在多条命令之间保持运行,所以这些命令感觉像同一个会话。完事后用 chrome-use close
(或 close --all)收尾。想更细地读页面、找元素、做交互,分别见
读取页面、定位元素、交互操作。
$ chrome-use open https://duckduckgo.com
$ chrome-use snapshot -i # 找到搜索框的 ref
$ chrome-use fill @e1 "chrome-use cli"
$ chrome-use press Enter
$ chrome-use wait --load networkidle
$ chrome-use snapshot -i # 现在的 ref 反映的是搜索结果
$ chrome-use click @e5 # 点一个结果
$ chrome-use screenshot result.png
@ref 会失效:页面一变就重新快照
Ref(@e1、@e2 …)在每次 snapshot 时重新分配。
它们会在页面变化的那一刻失效——导航的点击、表单提交、动态重渲染、弹窗打开之后都可能失效。
所以在一次导航或结构性变化之后、下一次用 ref 交互之前,先重新快照。
chrome-use snapshot -i 一次,用新的 ref。
@ref 也会自愈:不必为每次微小 DOM 变动都重新快照
每个 ref 都记录了一个指纹——role + 可访问名称 + 祖先路径。当你使用它时,如果原节点已经不在,
chrome-use 会自动在当前页面上重新定位到那个匹配的元素并继续执行。所以在一次
React / Vue 列表重渲染(标签没变)之后,click @e3 依然会命中正确的元素。
如果那个元素是真的没了,它会明确报错而不是去点一个错误的节点——它从不会悄悄打错目标。 因此:只有当你发生了导航,或者标签 / 结构真的变了时,才需要重新快照。
snapshot -i。
单纯的列表重渲染(标签不变)不用,交给 ref 自愈就好。
硬规则:快照优先,绝不靠截图定位
对于表单字段和按钮,永远先 snapshot -i,然后对 ref / selector 动手。
不要用 screenshot + 坐标点击去找元素或命中元素。
snapshot -i 现在能穿透跨域 iframe(内嵌的 Google Payments / Stripe / 结账 / KYC 表单),
把它们的元素连同输入值一起按 @ref 列出来——所以 click @e / type @e / fill @e
直接就能打进 iframe 里。只有 canvas / WebGL,或者 snapshot 对你的目标确实什么都返回不了时,才用坐标。
两种不同意图——只有一种被劝阻
上面这条规则针对的是 screenshot-to-locate(用一张图去找 / 命中元素)——那才是 bug。 而 screenshot-to-capture(把一块区域或某个元素存成文件,作为可复用的图片素材—— 地图、图表、og 图、视觉回归基线、报告插图)是完全支持且鼓励的:
# 把一块渲染出来的区域存成可复用的图片素材(不是用来定位)
$ chrome-use screenshot [selector] --clip x,y,w,h <file>
# 想点一个用 ref 命中不了的东西?box 给出元素的 CSS 像素框 + 中心点
$ chrome-use box @ref
$ chrome-use click <centerX> <centerY>
截图会自动降采样到最长边 ≤ 2000px,好让图像阅读器读得下、并让像素和 click x y 对齐;
用 --max-width / --max-height / --scale 可以覆盖。想点一个用 ref 命中不了的元素,
box @ref 会给出它的 CSS 像素框和 centerX/centerY,直接喂给 click <centerX> <centerY>——不需要截图。
canvas / WebGL 的坐标玩法见 截图 · 录像 · 视口 与画布相关章节。
两条驱动路径——以及何时切到 eval
你手上是一个带着用户真实 DOM 的真实 Chrome。有两层,可以随意混用:
snapshot + @ref、find、带类型的动作。方便、可读,适合直白的表单和导航。
但可访问性视图是有损而脆弱的:ref 一变就失效、隐藏 input 从不出现、遮罩会挡住坐标点击。
chrome-use eval "<js>"——你在真实 DOM 上的眼睛和手:读隐藏 input、探进 Shadow DOM / iframe、
查 form.elements 和 .validity、抽出你要的确切结构,或直接 el.click()。
eval,别反复重试它——
这是查明"为什么失败"最快的方式(比如一个 UI 从不暴露的隐藏 point_choice=none)。
别把一个不稳的结构化 locator 试三遍;直接掉到 eval 上对 DOM 动手。
# 列出表单里所有字段的 name / type / value / checked
$ chrome-use eval "[...document.forms[0].elements].map(e=>[e.name,e.type,e.value,e.checked])"
# 读一个 UI 从不暴露的隐藏字段
$ chrome-use eval "document.querySelector('[name=point_choice]')?.value"
# 找出所有校验不通过的字段和它们的报错信息
$ chrome-use eval "[...document.forms[0].elements].filter(e=>!e.validity.valid).map(e=>e.name+': '+e.validationMessage)"
# 直接 DOM 点击,绕过遮罩
$ chrome-use eval "document.querySelector('#stubborn').click()"
升级阶梯是:直白页面用 snapshot + @eN 最快 → 不想快照时用
find role/text/label → 原生 CSS selector → 上面任何一条跟你较劲的那一刻,就上 eval
直接对 DOM 动手。更多定位手段见 定位元素。
eval 默认在顶层文档的主世界执行,状态跨调用保留——所以顶层的 const x / let x
会和下一次调用冲突(Identifier 'x' has already been declared)。用唯一名字、挂到 window.x,
或把函数体包进 IIFE。带引号 / 非 ASCII / 大段脚本时用 eval --stdin(heredoc)、
eval --file <path> 或 eval -b <base64>,别用会被 shell 搅乱的内联写法。
下一步
把核心循环跑顺之后,按需深入: