会话与登录 / SESSIONS & AUTH

反检测与隐身

很多网站会主动拦截浏览器自动化——轻则挑战、验证码,重则直接封号。 Playwright/Puppeteer 加 stealth 插件那一类工具,都是在一个空白浏览器上「打补丁」冒充真人,而每个补丁都是反-bot 系统的破绽。 chrome-use 的答案不一样:它不去模拟真人,它本身就是你那个真实、已登录的浏览器。

为什么反检测是核心能力

任何在真实站点上跑的 agent,第一道门槛都不是「会不会点按钮」,而是会不会被当成机器人拦下来。 Akamai、PerimeterX、DataDome、Cloudflare 这类反-bot 供应商既看指纹(浏览器有没有自动化痕迹), 也看行为(鼠标怎么动、字怎么打)。一旦触发,代价往往不只是这一次请求失败——是这个账号被标记、被封。

所以 chrome-use 把反检测当作一等能力,而不是事后补丁。核心思路一句话: 优先驱动你真实、已登录的 Chrome——站点看到的就是一个货真价实的人类浏览器。 对确实需要隔离浏览器的场景,才用「原生覆盖 > JS 谎言」的方式把痕迹做干净。


核心理念:0% stealth = 什么都不改

连接你真实 Chrome(扩展 relay)时,chrome-use 注入的 JavaScript 补丁数量是 零。 你浏览器的指纹是完全真实的。指导原则是「原生 CDP/Chrome 覆盖优先于 JS 谎言」—— 一个被重定义的 getter 本身就可被检测,而一个原生覆盖不会。

✅ 为什么 0% 是最强的分数
CreepJS 上 0% stealth 是关键数字:因为连接路径什么都不改, 测谎器根本没有任何「覆盖」可抓。它不是「补丁做得好」,而是压根没有补丁——这是真实浏览器本身的分数。

实测数据

chrome-use 刻意不自带 bot 检测器——最诚实的基准,是拿市面上最强的检测站直接打你的真实浏览器。 以下是连接真实 Chrome 时的实测结果:

实测结果 · 连接真实 Chrome
# CreepJS —— 最严苛的指纹 / 测谎检测器
CreepJS            0% stealth · 0% headless   # 完全没有覆盖痕迹

# bot.incolumitas —— 行为 + 指纹综合评分(方法公开)
bot.incolumitas    all checks OK          # overflowTest / overrideTest /
                                          # puppeteerExtraStealthUsed / worker 一致性

# 经典自动化标记清单
bot.sannysoft      all green
BrowserScan        Webdriver · User-Agent · CDP 全部干净
Cloudflare managed challenge (scrapingcourse.com)  passed
ℹ️ 关于「soft flag」
某些仪表盘读 navigator.languages 顺序或 IP 地理位置时,可能给一个软性的 navigator / location 标记——那反映的是你真实 Chrome 的语言列表和网络,不是自动化痕迹。
有头启动保留原生指纹
有头 --launch 默认不再用 JavaScript 改写 CPU、GPU、UA Client Hints、屏幕或 iframe。 页面和 Worker 使用 Chrome 的真实属性。Canvas/音频噪声及 disable-devtool 兼容包装仍需显式开启,可能被检测到。 无桌面 Linux 主机建议通过 Xvfb 运行有头 Chrome。显式允许 headless 仍可能暴露 Worker 指纹; stealth status 会提示这一限制。基础探针通过不代表 Cloudflare 放行或账号安全。 CDP IME 提交产生的 compositionend 也可能被 Chrome 标记为 untrusted。

三层防线

反检测在 chrome-use 里是三层叠起来的:从「用哪个浏览器」到「指纹长什么样」再到「行为像不像人」。

① 真实会话 > headed > headless(禁用)

反检测等级排名:真实、已登录的 Chrome(扩展连接)> 有头 launched 浏览器 > headless(禁止)。 一个货真价实的人类浏览器完全没有 headless / 自动化的破绽,所以任何对反-bot 敏感的任务都优先用它。 headless 默认是被禁止的——它本身就是一个 bot 破绽(--headed 是 stealth 的默认且始终开启)。

bash · headed 默认
# --headed 是 stealth 的默认、始终开启 —— headless 被禁止
# (它是 bot 破绽:creepjs 对 headless 报 ~33%,对 headed 报 0%)
# 仅无显示器的服务器才放开:
$ AGENT_BROWSER_ALLOW_HEADLESS=1 chrome-use --launch open "https://example.com"

② 原生指纹覆盖

对隔离 / launched 浏览器,用原生覆盖把关键指纹对齐到你想要的身份——全都不是 JS 谎言, 测谎器抓不到。这些开关只作用于 --launch:

macOS 上的 launched Chrome 还会禁用 MacAppCodeSignClone。短生命周期自动化不需要 Chrome 为原地更新准备的代码签名克隆;禁用后,即使会话被强制结束,也不会留下随后膨胀占盘的 APFS 克隆。

bash · 指纹覆盖(--launch)
# 原生时区覆盖(IANA id,或 "auto" 从 locale 推导),Intl+Date 跟随,无 JS 谎言
$ AGENT_BROWSER_TIMEZONE="Asia/Tokyo" chrome-use --launch open "https://example.com"

# 通过 WebRTC 隐藏本机 IP(设了代理时自动强制走代理,不泄露真实 IP)
$ AGENT_BROWSER_BLOCK_WEBRTC=1 chrome-use --launch open "https://example.com"

# 会话内稳定的 canvas/audio 指纹噪声(默认关,因为噪声本身也是一种「谎言」)
$ AGENT_BROWSER_HIDE_CANVAS=1 chrome-use --launch open "https://example.com"
ℹ️ webdriver 也是原生覆盖
navigator.webdriver = false 走的是 Emulation.setAutomationOverride——原生实现, 不是重定义 getter,所以 CreepJS 那类测谎测不出来。

③ 行为层:--humanize 过 Akamai/PerimeterX/DataDome

指纹干净不是全部——最强的反-bot 供应商还给行为打分。一个把光标瞬移到元素正中心、零按压延迟的点击就是破绽, 即便我们的 CDP 事件是 isTrusted。开启 humanize 后,光标像手一样动:点击沿一条弯曲、 减速的贝塞尔轨迹落到元素内部一个抖动的点(绝不落在死正中心);打字用可变的击键间隔;滚动分段缓动;拖拽走曲线。

它是自适应的——每次导航都会探测已知的反-bot 供应商(cookie / 脚本 / 全局变量), 被守卫的页面自动升级到完整的 human 运动。其他页面从 1.5.255 起默认 fast:短曲线轨迹、落点抖动、 type 逐键输入、滚轮滚动,只慢一点。自带风控、厂商探测看不出来的网站(抖音、小红书、B站、X、微博、快手、知乎、淘宝、 京东、YouTube 等)一律 human。

bash · humanize
# off(瞬时)| fast(默认,轻量缓动轨迹)| human(完整曲线 + 落点抖动 + 打字节奏 + 缓动滚动/拖拽)
$ chrome-use --humanize human click "@ref=e42"

# 或用环境变量设定整个 session 的默认值
$ AGENT_BROWSER_HUMANIZE=human chrome-use type "hello"
✅ 让它保持 auto
默认 fast;自适应检测器会把被 Akamai/PerimeterX/DataDome 守卫的页面和上面的高风险网站升到 human。 只在没人盯着、又要速度的地方(本地测试页、内部工具)才用 off。

Cloudflare:一次通过、复用 clearance

通过一次 Cloudflare 挑战会铸出一个 cf_clearance cookie(HttpOnly——对 eval/document.cookie 不可见,用 chrome-use cookies 读它)。它绑定你的 IP + User-Agent:复用同一个出口 IP 和 UA,就能在它过期前跳过挑战。驱动用户真实 Chrome(relay) 会原生持久化它;隔离 session 用 --session-name <name> 保存 / 恢复。

在花力气去解之前,先跑 chrome-use cf-status(别名 cf、clearance)做预检—— 避免重复解一个已经过了的挑战。

bash · cf-status
# 预检:页面当前是否是 Cloudflare 挑战?是否已有有效的 cf_clearance?
$ chrome-use cf-status

# 读取 HttpOnly 的 cf_clearance cookie
$ chrome-use cookies
ℹ️ cf-status 给的三种建议
proceed(已通关,别再解)、solve(挑战在、无 clearance)、 reissue(有 clearance 但页面仍被挡 → IP/UA 漂移了,重新解)。把它当预检,别重复解已经过了的挑战。

隐身模式开关(扩展设置页)

扩展设置页有一个隐身模式开关,默认开启。开启时,chrome-use 不往它操作的网页里加任何自己的东西: 没有浮层,没有具名的页面全局变量,站点适配器的点击和输入通过 args.ui 用真实的输入事件完成。 会画进网页的功能只在关闭隐身模式后可用,目前是 agent 光标(柔和的光标和点击波纹),隐身开着时它的开关是灰的。 Inspect & Ask 由你自己触发,不受这个开关影响。

开启隐身模式或关闭 agent 光标时,扩展还会在进行中的绘制结束后移除已有的光标浮层、点击波纹和 window.__abCursor。清理通过现有调试连接执行,并确认节点和全局变量已移除。 如果标签页已断开或无法访问,设置页会提示清理尚未确认;依赖隐身模式前请重新加载相关页面。 正常重新连接标签页时会重试清理,切换设置不会强制建立连接。

ℹ️ 给贡献者
新功能只要网页能看到(DOM 节点、全局变量、事件监听、合成事件、固定节奏),隐身模式开着时就必须关闭。PR 和发版都会检查这一点,见 AGENTS.md 的「Stealth first」。

自检:chrome-use stealth status

任何时候都能自查当前的隐身状态:chrome-use stealth status 报告当前模式加上一组实时探针 (webdriver / chrome / plugins / UA),以及当前配置。加 --json 拿机器可读输出。headless、scope 和 warnings 说明诊断边界;已知 headless 启动不会报告全部通过。

bash · stealth status
# 隐身自检:模式 + 实时探针(webdriver / chrome / plugins / UA)+ 已生效的覆盖
$ chrome-use stealth status
$ chrome-use stealth status --json

相关页面