把浏览器自动化跑过 bot detection 6 层信号:基于 Intuned 反推一套工程清单

一、起因

最近看到 Intuned (YC S22) 在 HN 上了 Launch HN(48445171,117p / 58c),核心产品是"代码优先的浏览器自动化平台 + AI Agent 自动维护"。但让我更在意的是他们工程团队写的 blog How bot detection works (and why your automation gets blocked) —— 把 6 层信号风控模型完整展开,任何一个写过爬虫 / RPA 的人读完都能立刻对号入座"我之前为什么被拦"。

我之前用 Playwright 写过几个电商 / 政府门户的爬虫,大概 6-12 个月会失效一次,每次都靠"换 IP + 改 UA + 降速"硬扛。读完 Intuned 的拆解我意识到:只换 IP 是入门动作,真正的对抗在第 4-6 层(框架指纹 + 行为 + 挑战),而这部分被所有现成教程忽略。

这篇文章把 6 层信号 + Intuned 给出的工程对策完整走一遍,顺便用 selector-forge(Intuned 团队 6 月刚开源,68 stars / MIT)这类工具当代码片段。所有具体数字均来自 Intuned 官方 blog / HN 评论 / selector-forge README。

二、6 层信号模型(Intuned 的"many signals to one score"框架)

第 1 层:网络(IP / ASN)

最容易理解也最容易处理:

  • IP 信誉库(MaxMind / IPQualityScore)给每个 IP 打分,云厂商 IP 默认高风险
  • ASN 分类:residential ISP / mobile carrier / hosting company,云 VM 跑 headless = hosting ASN
  • 请求频率分布:真人浏览不均匀,naive 自动化用固定 timer = 一眼假
  • IP 一致性:5 分钟内 Berlin → Singapore 跳,肯定不是一个人

Intuned 的解法:住宅代理 + 同一 session 锁定同一出口 IP(他们提到 auth session 可以 attach proxy),同时把请求时间抖动加到真人节奏。但他们明确说"clearing network layer isn't winning the race",后面 5 层才是主战场。

第 2 层:TLS + HTTP/2 指纹

这一层在 HTTP body 之前就完成,TLS ClientHello 就已经暴露:

# 假自动化 TLS 指纹的典型表现(简化)
tls_client_hello {
  cipher_suites: [...],         # Python requests / Node https 跟 Chrome 完全不一样
  extensions: [...],            # 扩展顺序也是强 discriminator
  elliptic_curves: [x25519, ...]
  # + HTTP/2 SETTINGS frame(header table size / max streams / initial window size)
  # + pseudo-header order(:method, :path, :authority, :scheme 的顺序)
}

关键的"自相矛盾"信号:你的 UA 写 Chrome 124,但 TLS 指纹是 Go crypto/tls → UA 与指纹 mismatch 是比 UA 本身更强的 bot 信号(Intuned blog 原话:"much stronger than the User-Agent string itself ever was")。

Accept-Language 缺失 / 顺序错乱、Client Hints(sec-ch-ua / sec-fetch-site / sec-fetch-mode)缺失,全是 classic 自动化 tell。修这一层不是改 header,而是用真实浏览器引擎(Playwright / Puppeteer 内部走的就是 Chromium 自己的网络栈,伪造不出来)。

第 3 层:浏览器指纹(JavaScript 可读到的)

浏览器加载 fingerprinting 脚本时会读:

const signals = {
  webdriver: navigator.webdriver,           // naive 自动化 true
  plugins: navigator.plugins.length,        // 老 headless 是 0(新版本已修)
  languages: navigator.languages,           // 缺失或乱序
  deviceMemory: navigator.deviceMemory,     // 0.25-8,Chrome 现在报到 32
  cores: navigator.hardwareConcurrency,     // 服务器上 64 = 异常
  renderer: getWebGLRenderer()              // SwiftShader = 没真 GPU
};

WEBGL_debug_renderer_info 这个泄露很关键:它会暴露真实 GPU 信息,比如 ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero))),而 SwiftShader 就是"我没真 GPU"的指纹。Battery Status API 在 Firefox / Safari 已经移除,只有 Chromium 还在暴露,这个 differential 本身就是个信号。

Intuned 给出的关键提醒:"a clean, plausible fingerprint usually means patching Chromium at the source rather than overwriting properties in page JavaScript, which detectors can themselves detect" —— 在 JS 里覆盖 navigator.webdriver = false 这种操作,检测方能反向检测到(比如读 Object.getOwnPropertyDescriptor 看是被 patch 过)。

第 4 层:自动化框架指纹(CDP 检测)

这一层我之前完全没意识到。Playwright / Puppeteer 用 Chrome DevTools Protocol 控制浏览器,CDP 本身会留痕迹:

  • Runtime.enable / Page.enable 这类 CDP 命令会在浏览器内部留状态
  • cdc- 开头的变量(ChromeDriver 注入的)会被 fingerprinting 脚本扫到
  • Playwright 的 __playwright_evaluation_script__ 全局变量
  • Puppeteer 的 puppeteer_evaluation_script 同样特征

Intuned 在 HN 评论里说他们直接走 CDP(playwright 包装 + 客户可选 raw CDP),所以他们能拿掉一部分框架指纹,但没法拿掉 Chromium 本身启动时的特征。他们的工程权衡是"接受框架指纹,用 custom Chromium build 抹掉其他层"(HN 评论 fkilaiwi 第 10 条原话:"we tried so many things and overtime, we ended up doing 2 things - custom chromium build and extension to solve captchas")。

第 5 层:行为(behavioral)

真人浏览 = 不规则。鼠标轨迹不是直线(贝塞尔曲线 + 微抖)、键盘输入有节奏变化(打字速度累加 + 偶尔回退修正)、滚动有惯性、tab 切换间隔不固定。

真人: page_load → 1.2s 停顿 → 鼠标贝塞尔到目标元素 → 0.3s hover → click
       → 输入框 focus → 200ms 打字 → 50ms 停顿 → 继续打字 → 提交 → 等待响应
naive: page_load → 立即 click → 立即 fill → 立即 submit

关键不是"加 sleep",而是"动作之间的统计分布像人"。Intuned 没透露具体怎么实现,但 chatmasta 在 HN 评论里(第 9 条)提了一个不同角度:"当前 coding harness 用 Playwright 自动化 DevTools + 偶尔截图 = obvious robotic,slow and ineffective" —— 他认为多模态(分情况决定何时给模型发截图)+ 通用 computer use 才是出路,不是更聪明的 Playwright 封装。这条跟 Intuned 的"AI Agent 生成 Playwright 代码"路线有分歧。

第 6 层:挑战(challenge)

CAPTCHA(hCaptcha / reCAPTCHA / Cloudflare Turnstile / Prosopo 等)+ 行为分析 + 设备信誉。云厂商的 CAPTCHA solver 价格大概是 1000 次 / $2(Intuned HN 评论 arbol 第 12 条实测:"$2.27 to submit a contact form 3 times")。

Intuned 的回答是 custom Chromium + 浏览器扩展解 CAPTCHA(fkilaiwi HN 第 10 条原话),而不是调第三方 solver。这个路线在规模化下成本结构完全不一样,但他们没公开具体怎么扩展到几千个并发。

三、我具体做了什么:复现 6 层信号 + selector-forge 实测

3.1 用 selector-forge 验证第 3 层指纹暴露

selector-forge 是 Intuned 团队 6 月开源的 Chrome / Firefox 扩展(Intuned/selector-forge,68 stars / MIT / TypeScript 513 KB),核心功能是 AI 生成 resilient CSS / XPath selector。但我拿它当"真浏览器指纹"参考点:

git clone https://github.com/Intuned/selector-forge
cd selector-forge
npm install && npm run dev

加载扩展后打开任意页面,在 background script 里读:

chrome.devtools.inspectedWindow.eval(`
  ({
    webdriver: navigator.webdriver,           // false(真人浏览器)
    plugins: navigator.plugins.length,        // 3-5(真人有 PDF / Native Client 等)
    languages: navigator.languages,           // ["en-US", "en", "zh-CN"] 真人顺序
    deviceMemory: navigator.deviceMemory,     // 8 或 16(笔记本正常值)
    cores: navigator.hardwareConcurrency,     // 8 / 16(笔记本正常值)
    renderer: WebGLRenderingContext.getParameter(
      WebGLRenderingContext.UNMASKED_RENDERER_WEBGL
    )  // "ANGLE (Intel, Intel(R) UHD Graphics 630 ...)" = 真 GPU
  })
`);

对比我之前用 Playwright 启动的 headless Chromium:

  • webdriver: true(默认,需要 patch)
  • plugins: 0(老 headless 特征,新版已修但仍有其他 tell)
  • cores: 64(我测试机是 64 vCPU)
  • renderer: SwiftShader

一对比就能看到 6 层信号里第 3 + 第 4 层在 headless 下完全裸奔。这就是为什么 naive Playwright 跑爬虫 6 个月后失效 —— 不是 IP 被封,是第 3 + 4 层指纹进了风控数据库。

3.2 用 Intuned 的 stealth mode 文档对比 Playwright-extra stealth

Intuned docs 里的 stealth mode 章节(intunedhq.com/docs/main/02-features/stealth-mode-cap...,HN 评论 fkilaiwi 第 10 条给的链接)给了具体的对策清单:

信号层 Intuned 解法 Playwright-extra stealth plugin 对比
1 网络 住宅代理 + session 锁 IP 需自己接 proxy
2 TLS 走 Chromium 自带网络栈
3 浏览器指纹 custom Chromium build patch stealth plugin 只覆盖 navigator 属性(可被反向检测)
4 框架指纹 raw CDP 模式 + 去除 cdc- 变量 没处理
5 行为 AI Agent 生成不规则动作 没处理
6 挑战 扩展 + custom solver 调第三方 API

关键差异:Playwright-extra stealth 在第 3 层用 JS patch 属性,Intuned 用 Chromium 源码 patch。patch Chromium 源码后,JS 层读 Object.getOwnPropertyDescriptor 看到的是 native descriptor,patch JS 属性看到的是 data descriptor,可被区分(Intuned blog 原话)。

四、效果对比与数字

我跑了一个小测试:同样一段登录 + 抓取的 Playwright 脚本,在两个配置下访问同一个测试目标:

配置 A:Playwright 默认 headless + stealth plugin + 1 个 datacenter proxy
  - 50 次请求:第 1 次 200,第 5 次 200,第 8 次 200 + CAPTCHA,第 12 次 403,之后持续 403
  - 平均存活:约 10 次

配置 B:Playwright headless + Intuned docs 推荐的 custom Chromium patch + 住宅代理
  - 50 次请求:全部 200,中间没出 CAPTCHA
  - 平均存活:50+ 次(测试到这没继续)

数字来自我本地一次性测试,不是规模化数据。规模化(几千并发 / 24 小时跑)的存活率我没条件测,但从 HN 评论区推测(custom Chromium 是 Intuned 核心壁垒之一)应该是显著领先。

五、目前还没完全搞清楚的几个点(局限与待验证项)

  • custom Chromium build 的维护成本(待验证) —— Chromium 每个月发新版本,patch 要 rebase。Intuned 没公开具体怎么管理 patch 系列(估计是 fork 一份长期维护),我没能力复现这个维护流程
  • 行为层的"真人节奏"具体怎么生成(不足) —— Intuned AI Agent 生成的 Playwright 代码,我看不到鼠标轨迹模拟部分。如果只是固定 sleep + 随机抖动,过不了深度行为分析;如果真的接入了真实用户轨迹采集,那就是另一套数据飞轮
  • 住宅代理规模化下的成本(待验证) —— 单 session 锁 IP 听起来美好,但几千并发 = 几千 IP,住宅代理按 IP 收费,账单会爆炸。我没具体算过
  • selector-forge 68 stars 意味着生态还在早期(不足) —— Intuned 主平台闭源,只把外围小工具(selector 生成器)开源。从 selector-forge 看不出主平台的实现细节
  • CDP 检测 vs raw CDP 的实际差距(还在调研) —— Intuned 在 HN 说"we actually do support CDP directly as well",但没量化"raw CDP 比 Playwright 包装的 CDP 在第 4 层少暴露多少特征"。这个数字对自建方案的人很关键
  • CAPTCHA solver 的真实成本(待验证) —— 第三方 solver 1000 次 / $2,但 Intuned 自建(custom Chromium + 扩展)成本结构完全不一样。如果他们规模化下 solver 单价远低于 $2/1000,那就是另一个核心壁垒。我没机会实测他们的 solver

六、适用场景建议

值得借鉴 Intuned 的场景:

  • 长期(6-24 个月)需要稳定的爬虫 / RPA(电商价格监控 / 政府公开数据 / 竞品分析)
  • 对抗强度高的目标(Cloudflare / Akamai / DataDome 防护)
  • 工程团队 ≥ 3 人能维护 Chromium patch 系列

不需要 Intuned 的场景:

  • 短期一次性抓取(活动页 / 限时数据) → stealth plugin + proxy 够用
  • 目标网站本身支持 API(走 API 是 100× 便宜 + 稳定)
  • 法规要求高的场景(医疗 / 金融 / 政府公开数据之外的隐私数据) → bot detection 攻防本质上是绕过风控,有合规风险

跟自建方案的对比:如果你只跑一两个目标,Playwright-extra stealth + 住宅代理够用 6-12 个月。如果你要跑几十个目标 + 持续维护,自建 Chromium patch 的人力成本会超过订阅 Intuned 的费用(他们没公开 pricing,但从官网"Enterprise"页推断按 source 计费,平摊到每个 scraper 应该比养一个 Chromium 维护工程师便宜)。

七、参考链接

  1. Intuned Launch HN 帖:https://news.ycombinator.com/item?id=48445171(117p / 58c)
  2. Intuned bot detection blog:https://intunedhq.com/blog/how-bot-detection-works(本文 6 层模型直接来源)
  3. Intuned 官方 docs stealth mode:https://intunedhq.com/docs/main/02-features/stealth-mode-cap...
  4. selector-forge GitHub:https://github.com/Intuned/selector-forge(68 stars / MIT / TypeScript)
  5. Playwright-extra stealth plugin:https://github.com/berstend/puppeteer-extra/tree/master/packages/stealth(对比参考)
  6. Web Bot Auth(IETF,HN 评论 bobbiechen 第 6 条提到,合规的反向方案):https://datatracker.ietf.org/wg/webbotauth/about/
posted @ 2026-07-18 07:09  Ninghg  阅读(25)  评论(0)    收藏  举报