会话与登录 / 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 本身就可被检测,而一个原生覆盖不会。
-
navigator.webdriver = false通过Emulation.setAutomationOverride实现(原生, CreepJS 那类「测谎」测不出来)。 -
Runtime.enable默认关闭。 一个活跃的Runtime域是可被检测的 CDP 信号 (patchright/rebrowser 说的「runtime leak」)——即便是连着你真实 Chrome 也一样。只有当你主动开启 console/错误捕获时才启用它;click、fill、eval等在不开它的情况下照常工作。
实测数据
chrome-use 刻意不自带 bot 检测器——最诚实的基准,是拿市面上最强的检测站直接打你的真实浏览器。 以下是连接真实 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 Turnstile (nowsecure.nl) passed
navigator.languages 顺序或 IP 地理位置时,可能给一个软性的 navigator /
location 标记——那反映的是你真实 Chrome 的语言列表和网络,不是自动化痕迹。
--launch 隔离浏览器的一个 caveat--launch(独立浏览器)时会改为应用一整套 stealth 补丁,同样能通过上面这套检测——
但 CreepJS 会报 ~20% stealth,因为 srcdoc-iframe 的 contentWindow 补丁触发了它的
hasIframeProxy 探针(那个用来藏自动化的 proxy 本身成了破绽)。其余全干净(0% headless,
sannysoft/browserscan 全绿,Cloudflare 通过)。设 AGENT_BROWSER_DISABLE_IFRAME_PROXY=1 去掉那个补丁
即可拿到干净的 0% stealth。而扩展连接路径(你真实的 Chrome)注入零 JS,不受影响——它就是那个真正的 0% 路径。
三层防线
反检测在 chrome-use 里是三层叠起来的:从「用哪个浏览器」到「指纹长什么样」再到「行为像不像人」。
① 真实会话 > headed > headless(禁用)
反检测等级排名:真实、已登录的 Chrome(扩展连接)> 有头 launched 浏览器 > headless(禁止)。
一个货真价实的人类浏览器完全没有 headless / 自动化的破绽,所以任何对反-bot 敏感的任务都优先用它。
headless 默认是被禁止的——它本身就是一个 bot 破绽(--headed 是 stealth 的默认且始终开启)。
# --headed 是 stealth 的默认、始终开启 —— headless 被禁止
# (它是 bot 破绽:creepjs 对 headless 报 ~33%,对 headed 报 0%)
# 仅无显示器的服务器才放开:
$ AGENT_BROWSER_ALLOW_HEADLESS=1 chrome-use --launch open "https://example.com"
② 原生指纹覆盖
对隔离 / launched 浏览器,用原生覆盖把关键指纹对齐到你想要的身份——全都不是 JS 谎言,
测谎器抓不到。这些开关只作用于 --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"
navigator.webdriver = false 走的是 Emulation.setAutomationOverride——原生实现,
不是重定义 getter,所以 CreepJS 那类测谎测不出来。
③ 行为层:--humanize 过 Akamai/PerimeterX/DataDome
指纹干净不是全部——最强的反-bot 供应商还给行为打分。一个把光标瞬移到元素正中心、零按压延迟的点击就是破绽,
即便我们的 CDP 事件是 isTrusted。开启 humanize 后,光标像手一样动:点击沿一条弯曲、
减速的贝塞尔轨迹落到元素内部一个抖动的点(绝不落在死正中心);打字用可变的击键间隔;滚动分段缓动;拖拽走曲线。
它是自适应的——每次导航都会探测已知的反-bot 供应商(cookie / 脚本 / 全局变量),
被守卫的页面自动升级到完整的 human 运动,而普通站点保持即时(零开销)。
# off(默认,瞬时)| fast(轻量缓动轨迹)| human(完整曲线 + 落点抖动 + 打字节奏 + 缓动滚动/拖拽)
$ chrome-use --humanize human click "@ref=e42"
# 或用环境变量设定整个 session 的默认值
$ AGENT_BROWSER_HUMANIZE=human chrome-use type "hello"
off,自适应检测器会把被 Akamai/PerimeterX/DataDome 守卫的页面自动升到 human。
只有当你已经确知目标在给行为打分时,才手动强制 human。
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)做预检——
避免重复解一个已经过了的挑战。
# 预检:页面当前是否是 Cloudflare 挑战?是否已有有效的 cf_clearance?
$ chrome-use cf-status
# 读取 HttpOnly 的 cf_clearance cookie
$ chrome-use cookies
proceed(已通关,别再解)、solve(挑战在、无 clearance)、
reissue(有 clearance 但页面仍被挡 → IP/UA 漂移了,重新解)。把它当预检,别重复解已经过了的挑战。
自检:chrome-use stealth status
任何时候都能自查当前的隐身状态:chrome-use stealth status 报告当前模式加上一组实时探针
(webdriver / chrome / plugins / UA),以及已生效的覆盖。加 --json 拿机器可读输出。
# 隐身自检:模式 + 实时探针(webdriver / chrome / plugins / UA)+ 已生效的覆盖
$ chrome-use stealth status
$ chrome-use stealth status --json