全部文章
1 分钟阅读glizzykingdreko

DataDome 到底是如何识别机器人的

DataDome 如何根据设备指纹、TLS 和行为标签为请求打分,无头浏览器为何会被抓,以及一个能通过检测的请求长什么样。

DataDome 到底是如何识别机器人的

大多数人第一次撞上 DataDome 的方式都差不多:昨天还能跑的爬虫今天开始返回 403,或者原本是页面的地方冒出了一个滑块验证码。第一反应往往是加个代理、换个 user agent。这几乎没用,因为 DataDome 并不是盯着某一个单独的信号看。它是在给整个请求的"画像"打分,而正确的做法是发送一张看起来真实的画像。

下面就是它实际会看的东西。

设备指纹

DataDome 的 JavaScript 在页面里运行,收集客户端的指纹:屏幕和窗口尺寸、时区、语言、已安装的字体、canvas 和 WebGL 哈希、支持的编解码器列表,以及数十个更细小的信号。单看这份指纹并不构成判决。它是 DataDome 跨请求追踪的一个身份标识,所以任何不一致或不可能的组合(比如一个"Chrome on Windows"的 user agent 却配着 Linux 的 WebGL 渲染器)会立刻显得格格不入。

TLS 与请求头顺序

在任何 JavaScript 运行之前,DataDome 已经从连接本身拿到了两个很强的信号:

  • TLS 指纹(JA3/JA4)。你的 HTTP 客户端提供的具体加密套件和扩展,几乎不可能和真实浏览器完全一致。默认的 requestsaxios 握手,和 Chrome 的握手轻而易举就能区分开。
  • 请求头的顺序和大小写。浏览器按一个特定且稳定的顺序发送请求头。大多数 HTTP 库并不会,DataDome 在读取任何请求头的值之前,就已经把这个顺序当成了破绽。

这就是为什么单换 User-Agent 字符串毫无作用。字符串说自己是 Chrome,握手却说这是 Python。

行为标签

页面加载后,DataDome 会向它的采集端点回传一批行为 标签(tags):鼠标移动、滚动时序、按键节奏、focus 和 blur 事件,以及它们之间的时间间隔。一个真实会话产生的是杂乱、带有人类形态的数据流。无头浏览器要么什么都不产生,要么产生的东西太干净、太快。

对这批数据的响应,正是设置 datadome cookie 的东西。把 payload 做对了,cookie 就以受信任的状态返回。做错了,或者干脆跳过,你拿到的就是拦截页或者滑块。

无头浏览器为什么还是会被抓

跑 Puppeteer 或 Playwright 能生成真实的标签和真实的 TLS 握手,所以它比裸的 HTTP 客户端能通过更多检测。但它慢(每个会话要几秒,每个 worker 要几百 MB 内存),而且会留下自己的指纹:navigator.webdriver、无头模式特有的渲染怪癖,以及自动化框架的时序模式——这些 stealth 插件总是慢一个版本才补上。最后你要同时维护一个浏览器农场和一场插件的追赶游戏,去对付一个更新速度比你还快的检测器。

一个能通过的请求长什么样

一个 DataDome 信任的请求,会带上三样彼此吻合的东西:

  1. 一个处于已通过状态的 有效 datadome cookie
  2. 该 cookie 签发时对应的 TLS 指纹和请求头集合
  3. 一个来自符合目标策略的 IP 的下游请求(自带代理)。

难点在于不用浏览器就能产出前两样。而这正是我们做的事:生成 tags payload,在服务端解决设备检测和滑块,把 datadome cookie 连同它签名时对应的请求头集合一并交回给你。你把它们附到自己的请求上,直接拿数据。不用无头 Chrome,不用 stealth 插件,不用玩猫鼠游戏。

如果你想了解具体机制和一个可用的示例,看 DataDome 绕过页面。如果拦你的是另一家厂商,完整的防护墙列表 覆盖了 Akamai、Cloudflare、PerimeterX、Imperva 以及其余各家。

datadomedetectionscraping

跳过逆向工程。

Takion 为每一道主流反机器人防护墙返回新鲜的 cookie、请求头和令牌。一次 POST,无需浏览器,一小时内完成首次调用。