跳转到主要内容
Guide

undetected-chromedriver 2026 失效:为何被识别以及如何修复

2026-06-078 分钟阅读

如果你的 undetected-chromedriver 脚本去年还能用,如今却卡在 'Just a moment...'、抛出 403,或者眼睁睁看着 Turnstile 组件无尽地转圈,那并不是你做错了什么。这个库本身并没有从根本上崩坏。只是 Cloudflare 已经把检测推进到了 undetected-chromedriver 当初设计来隐藏的那些破绽之外。

本文会通俗地讲清楚:undetected-chromedriver(UC)究竟做了什么、为什么现代 Cloudflare 依然能识别它,以及如何解读你看到的各种症状。我们会先从诚实的免费修复方法讲起,并指明它们究竟在哪里碰壁,然后介绍当你需要不会每次 Cloudflare 更新就崩溃的自动化时的务实路径:要么继续驱动浏览器但把挑战外包出去,要么彻底放弃浏览器,通过一次简单的 HTTP 调用取回 cf_clearance。

undetected-chromedriver 究竟做了什么

undetected-chromedriver 是 Selenium 的 ChromeDriver 的一个打过补丁的构建版本。原版 ChromeDriver 会留下明显的指纹:它把 navigator.webdriver 设为 true,在 document 对象里注入一个 bot 检测器会去搜索的 cdc_ 变量,并触发若干 Chrome DevTools 协议(CDP)破绽。UC 给 ChromeDriver 二进制文件和启动参数打补丁,剥离这些信号,因此一个刚启动的浏览器看起来远比默认的 Selenium 会话更像人类的 Chrome。

在很长一段时间里,这就足够了。Cloudflare 较旧的检查严重依赖的正是这些自动化破绽,所以移除它们往往就是 403 和 200 之间的区别。UC 之所以成为 '用真实浏览器抓取 Cloudflare 站点' 的默认推荐,正是因为它掩盖了那些容易暴露的痕迹。而 2026 年的问题在于,那些容易暴露的痕迹已不再是 Cloudflare 所关注的东西。

为什么现代 Cloudflare 仍能识别它

Cloudflare 当前的 bot 管理并不依赖单一破绽。它叠加了多个相互独立的检测系统,而 undetected-chromedriver 只处理其中最古老的那一层:

  • UC 无法通过的 Turnstile 与托管挑战:Turnstile 会运行一个非交互式的工作量证明(proof-of-work)外加浏览器 API 探测,然后才签发一个 cf-turnstile-response token。托管挑战会按每次请求动态挑选检查项。UC 能渲染这些组件,但它没有任何逻辑去真正生成有效 token 或攻克一个困难的托管挑战,因此页面始终无法前进。
  • CDP 与运行时泄露:UC 通过 DevTools 协议驱动 Chrome,而这个连接本身就是可观测的。检测器会探测 CDP 痕迹、时序异常,以及只有在浏览器被自动化时才存在的运行时对象。给 navigator.webdriver 打补丁并不会移除其底下的 CDP 表面。
  • TLS / JA3 指纹:在任何 JavaScript 运行之前,Cloudflare 就会检查 TLS ClientHello。自动化技术栈的握手可能与真正的消费级 Chrome 产生偏差,而 JA3/JA4 不匹配在第一个数据包就会被标记,无论 JS 环境看起来多么干净。
  • navigator.webdriver 与堆栈追踪破绽:即便打补丁修掉了明显的标志位,错误堆栈追踪、被注入的函数签名,以及微妙的属性描述符差异仍会出卖自动化。现代检测脚本读取的正是这些更高阶的破绽,而不只是 UC 修复的那个布尔值。
  • 维护放缓:这种猫鼠游戏只有在补丁跟得上 Chrome 与 Cloudflare 发版时才有效。UC 的维护已经放缓,而同一位维护者现在引导大家转向 nodriver——一个以远少得多的 CDP 痕迹与 Chrome 通信的继任者。如果你还在用 UC,你的部分问题可能仅仅是补丁落后了。

解读你看到的症状

你得到的错误会告诉你是哪一层抓住了你。把症状对上原因,可以省去瞎猜:

  • 卡在 'Just a moment...':过渡页加载了,但挑战始终没有通过。你的浏览器被要求自证身份却没通过检查,要么是因为 CDP/运行时泄露,要么是因为这是一个 UC 无法求解的困难托管挑战。
  • 普通 403(或 error 1020):你在握手之前或握手期间就被标记了,通常是 TLS/JA3 不匹配或低信誉的数据中心 IP。Cloudflare 直接拒绝了你,甚至没有下发挑战。
  • Turnstile 组件始终不通过:表单渲染出了一个 Turnstile 框,它一直转圈或不断重置。UC 没有任何 token 求解路径,因此该组件永远无法生成可用的 cf-turnstile-response,你的提交也就失败了。
  • 即使 headless=False 也被检测到:一个常见的意外。以非无头模式运行确实移除了无头破绽,但它对 CDP 痕迹、TLS 指纹或托管挑战毫无作用。一个可见的窗口并不等于一个不可检测的窗口。

值得先试的免费修复

在为任何东西付费之前,先把免费选项用尽。对于较轻量的 Cloudflare 配置,这些方法确实有效,没必要给只做被动检查的站点过度设计。

按工作量从小到大依次尝试:

  • 升级 UC 和 Chrome:相当一部分 'undetected-chromedriver 失效' 的报告,不过是针对较新 Chrome 的一个过时补丁而已。先固定匹配的版本并更新,再做其他任何事。
  • 切换到 nodriver:同样出自那位维护者,nodriver 彻底抛弃了 Selenium/ChromeDriver 这一层,以远少得多的 CDP 痕迹直接驱动 Chrome。它是预期中的现代替代品,往往能搞定 UC 已经拿不下的站点。
  • 使用持久化的 user-data-dir:复用一个真实的 Chrome 配置文件,让 cookie、本地存储以及先前的 cf_clearance 在多次运行之间得以保留。一个 '热' 配置文件远比每次启动都被挑战的新配置更像人类。
  • 在真实显示器上以非无头模式运行:无头模式会增加破绽。一个真正的窗口化浏览器(或服务器上的 xvfb)能移除这个特定信号,不过如上所述,它本身并非根治之法。
  • 通过干净的住宅代理路由:数据中心 IP 会被快速标记。轮换的住宅或移动 IP 能提高你的信誉分,减少一刀切式的 403。

免费修复在哪里到头

对这里的上限要对自己诚实。即便是一套完全调优的 UC 或 nodriver 配置,也带有任何补丁都消除不了的硬性限制:

驱动真实浏览器很重:每个实例都要吃掉数百兆内存和实打实的 CPU,因此扩展到多个并发 worker 会迅速变得昂贵且脆弱。这套技术栈仍然可被指纹识别,因为即便明显的标志位已被移除,CDP 痕迹、TLS 偏差以及更高阶的运行时破绽依然存在。而关键在于,这些工具都无法求解 Turnstile token:它们能把组件显示给你,却无法铸造出有效的 cf-turnstile-response,因此任何由 Turnstile 把守的表单都会一直关着。当目标下发一个困难的托管挑战或一个 Turnstile 组件时,仅靠给浏览器打补丁就走到尽头了。

务实路径:把困难部分外包出去

一旦撞上打过补丁的浏览器也攻不下的那些层,务实之举就是别再试图在打补丁上压过 Cloudflare,而是把那个特定的困难步骤交给一个为此而生的服务。这有两种形态。

第一,你可以让浏览器继续负责所有能正常工作的部分,只在需要 Turnstile token 或托管挑战清除时调用一个托管 API。第二,通常也更简单,你可以彻底放弃浏览器:许多抓取任务一旦持有有效的 cf_clearance cookie 就不再需要真实浏览器,于是你通过一次 HTTP 调用取回那个 cookie,其余流程都跑在一个普通的 requests session 上,以原生速度运行。

NSLSolver 正是为这种外包而生的开发者 API。它在单一 HTTP 契约背后处理 Cloudflare Turnstile、Cloudflare Challenge(托管/JS 挑战)以及 Kasada。它不求解 reCAPTCHA、hCaptcha、DataDome 或图像验证码,因此这是专门在 Cloudflare 或 Kasada 成为你的拦路墙时才合适的工具。Turnstile 求解平均约 250ms,成功率 99.9%,按成功求解计费,因此失败的求解免费;定价为按量付费:Turnstile 每 1,000 次求解 $0.40,Cloudflare Challenge 每 1,000 次 $0.50,Kasada 每 1,000 次 $1.50。新账户注册即送 100 次免费请求,无需信用卡、无需加密货币即可开始。

在 Python 中用 NSLSolver 取回 cf_clearance

下面这个版本针对托管/JS 挑战彻底替换掉了浏览器。你把目标 URL POST 到 /solve,取回你必须在自己的 session 上重放的 cookies 和 User-Agent。cf_clearance 值存放在一个以 cf_clearance 为键的 cookies 字典内,因此用 session.cookies.update(...) 应用它,并把 User-Agent 请求头设为返回的 user_agent,使你的指纹与签发该 cookie 时所用的指纹相匹配。

请准确注意字段名:响应字段是 user_agent(snake_case 蛇形命名),而 cookies 是一个字典,不是列表。Cloudflare 会把 clearance cookie 与那个特定的 User-Agent 绑定在一起,所以请始终回传 API 返回的值,而不是你自己的。如果你要保留浏览器,则改为请求一个 Turnstile token:POST type 'turnstile' 并附上组件的 site_key 和页面 url,然后把返回的 token 注入为 cf-turnstile-response 的值。

nslsolver_clearance.py
import requests

API = "https://api.nslsolver.com"
HEADERS = {"X-API-Key": "nsl_YOUR_API_KEY"}
TARGET = "https://target-site.com"

# 1) Hand the Cloudflare managed/JS challenge to NSLSolver
resp = requests.post(
    f"{API}/solve",
    headers=HEADERS,
    json={
        "type": "challenge",
        "url": TARGET,
        "proxy": "http://user:pass@host:port",
    },
    timeout=120,
)
data = resp.json()

# 2) Replay the cf_clearance cookie + matching User-Agent
#    on a plain requests session -- no browser needed
session = requests.Session()
session.cookies.update(data["cookies"])             # dict keyed by cf_clearance
session.headers["User-Agent"] = data["user_agent"]  # snake_case field

# 3) Scrape at native speed -- the request looks like a cleared browser
page = session.get(TARGET)
print(page.status_code)   # 200
print(page.text[:500])

常见问题

undetected-chromedriver 在 2026 年是不是已经死了?

没死,但它的优势已经被磨薄了。它仍能剥离明显的 Selenium 自动化破绽,这对较轻量的 Cloudflare 配置已经够用。但面对现代 Turnstile、困难的托管挑战、CDP/运行时探测以及 TLS 指纹时,它越来越频繁地失败,而且它的维护已经放缓。对于新项目,同一位维护者的 nodriver 是更好的浏览器侧起点。

undetected-chromedriver 和 nodriver 有什么区别?

undetected-chromedriver 给 Selenium 的 ChromeDriver 打补丁以隐藏自动化破绽。nodriver 出自同一位维护者,它抛弃了 Selenium/ChromeDriver 这一层,直接驱动 Chrome,因而留下的 CDP 痕迹少得多。nodriver 是预期中的现代继任者,往往能搞定 UC 已经拿不下的站点,不过两者本身都无法求解 Turnstile token。

为什么 undetected-chromedriver 会卡在 'Just a moment...'?

过渡页加载了,但挑战始终没有通过。要么 Cloudflare 通过 CDP/运行时泄露或 TLS 不匹配检测到了自动化,要么它下发了一个浏览器无法求解的困难托管挑战。以非无头模式运行修不了这个问题,因为窗口是否可见与底层的 CDP 和指纹破绽毫无关系。

undetected-chromedriver 能求解 Cloudflare Turnstile 吗?

不能。UC 能渲染 Turnstile 组件,但它没有任何逻辑去生成有效的 cf-turnstile-response token,因此组件会一直转圈或重置,你的表单提交也会失败。要拿到真正的 token,你需要一个能求解 Turnstile 的服务,或者一个返回 cf_clearance cookie 的托管挑战端点,具体取决于是哪一个在拦你。

如果用了 NSLSolver,我还需要浏览器吗?

通常不需要。对于托管/JS 挑战,NSLSolver 返回一个 cf_clearance cookie 和匹配的 User-Agent,你把它们应用到普通的 requests.Session 上,就能放弃浏览器、通过纯 HTTP 抓取。如果你想继续驱动浏览器,也可以改为只请求一个 Turnstile token 并把它注入页面,从而让你现有的其余流程保持不变。

别再给一个 Cloudflare 早已看穿的浏览器打补丁

把 Turnstile token 或托管挑战外包给一次 HTTP 调用,取回你的 session 所需的 cf_clearance。NSLSolver 处理 Turnstile、Cloudflare Challenge 和 Kasada——注册即送 100 次免费请求,无需信用卡。