网上大多数“如何绕过 Cloudflare”的教程在 2024 年底就失效了。原因不是 Cloudflare 加了新防御,而是旧防御(JA3 指纹 + 基础 header 检查)被换成了一代新机制,把所有捷径都打掉了。本文讲清 2026 年 Cloudflare 到底检查什么,为何 cloudscraper、undetected-chromedriver 和大多数“stealth”插件失效,以及生产环境仍然有效的四层配方。
先说实话:没有单一妙招。可靠绕过 Cloudflare 需要对的 IP、对的 TLS 指纹、对的 HTTP/2 帧顺序,以及(在 Bot Management 级别)一个真浏览器。任意一项搞错,你的请求还没到源站就在边缘被拦下。
Cloudflare 的机器人检测是边缘的一条过滤流水线。每个请求按顺序经过它们,最早拒绝的那个生效 —— 也就是说一个请求可能光凭 IP 信誉就失败,根本轮不到指纹或 header。
这是第一道、也是最省成本的检查。Cloudflare 维护一个按 ASN(自治系统号)索引的数据库。知名云厂商的 ASN(AWS AS16509、GCP AS15169、Azure AS8075、OVH、DigitalOcean、Hetzner、Vultr)受到最严审查。哪怕你有完美的浏览器级指纹,来自这些 ASN 的请求也是“未证清白即有罪”。
住宅 ASN(Comcast、Verizon、中国电信 AS4134、BT)默认合法。一个住宅 IP 配上笨拙的 Python 指纹仍可能通过,而一个数据中心 IP 配上完美 Chrome 指纹则会被挑战或拦截。
JA4 是 2023 年 JA3 的继任者,由 FoxIO 发布。它哈希 TLS ClientHello 的特定字段:TLS 版本、加密套件(按序)、扩展(按序)、ALPN、签名算法、支持的曲线,输出一个确定性指纹,形如 t13d1516h2_8daaf6152771_b1ff8ab2d16f。
真实 Chrome 124 产生一个特定 JA4,真实 Firefox 产生另一个。Python 的 requests(用 urllib3 + OpenSSL)产生的 JA4 没有任何真实浏览器会发出 —— 因为加密套件顺序和扩展列表既不像 Chrome 也不像 Firefox。Cloudflare 在解析任何 HTTP header 之前就标记掉这个模式。含义:任何使用系统 OpenSSL 或原生 Python TLS 的库都可被检测,包括 requests、aiohttp、默认配置的 httpx,以及基于它们的任何“绕过”封装。
浏览器以特定顺序和特定值发送 SETTINGS、WINDOW_UPDATE、HEADERS 等帧。Chrome 124 的 SETTINGS 取值、随后的 WINDOW_UPDATE 都是固定的;Python httpx 开 HTTP/2 时发的 settings 不同,还会漏掉 Chrome 带的 priority 帧。伪头部顺序也泄露身份:Chrome 发 :method、:authority、:scheme、:path,Firefox 顺序不同,多数 Python/Go 库则按字母序。Cloudflare 会拿它和声明的 User-Agent 应有的模式对比,不一致就标记。
真实 Chrome 以固定顺序发送 header(Host、Connection、sec-ch-ua… Accept-Language)。requests 会重排、有时大小写不同。即使你手动按正确顺序设置,底层库也会重新排序。
若前面过了但评分仍可疑,Cloudflare 下发 JS 挑战:脚本从浏览器环境值(canvas 哈希、WebGL、音频上下文、navigator 属性、计时)算出 token 并经 XHR 提交。没有任何 HTTP 客户端能解。你需要真浏览器,且它必须像真的(没有 navigator.webdriver = true、不缺属性)。
企业版会通过持续运行的脚本采集鼠标移动、滚动速度、点击时机、按键节奏。一个加载页面就立刻线性滚动、像素级精准点击的无头浏览器,几秒内就被识破。
2021–2024 的捷径工具有一个共同失败模式:它们打补丁的是可见表层,而不是底层 TLS 栈。
| 工具 | 它补什么 | 2026 年为何失效 |
|---|---|---|
cloudscraper | 旧版 JS 挑战求解 | Cloudflare 2023 转向 Turnstile,旧挑战已弃用 |
undetected-chromedriver | 打补丁 Selenium 泄露标志 | 底层 chromedriver 的 JA4 仍泄露;navigator.webdriver 只是 40+ 信号之一 |
selenium-stealth | 注入伪造 JS 属性 | Cloudflare 从 C++ 层读取,不看 JS;伪造反成不一致信号 |
FlareSolverr | 包一个 Chromium 一次性解挑战 | cf_clearance 绑定求解器 IP;换代理立即失效 |
原版 puppeteer-extra-plugin-stealth | 补 ~17 个检测点 | Cloudflare 在 2024–2025 新增 ~12 个未覆盖的检查 |
规律很清楚:包真浏览器、补已知泄露的工具,几个月就输掉军备竞赛;模拟浏览器 TLS 栈的工具(curl_cffi、tls-client)因为更贴近底层而活了下来。
2026 年能用的绕过需要全部四层,缺一层成功率就掉到个位数。
对任何跑 Cloudflare Pro 及以上的站点,这是不可妥协的。IP 信誉过滤会在 TLS 握手完成前就拒掉数据中心 ASN。用住宅代理 + 至少 10 分钟的 sticky 会话,让 cf_clearance cookie 存活。
用 curl_cffi(Python)或 tls-client(Go/Python)。两者都链接到一个改造版 BoringSSL,自带 Chrome 精确的加密套件顺序、扩展列表和 ALPN 值。
from curl_cffi import requests
response = requests.get(
"https://target.com/api/products",
impersonate="chrome124",
proxies={"https": "http://USERNAME-session-abc123:[email protected]:10001"},
timeout=30,
)
print(response.status_code, len(response.text))
impersonate="chrome124" 会把 TLS 栈换成与 Chrome 124 逐字节一致的 ClientHello,JA4 哈希与真实 Chrome 124 相同。配上住宅代理,你就过了前两道过滤。
用 impersonate 时 curl_cffi 会自动按 Chrome 顺序设置 header。要加自定义 header 就追加在末尾,别插中间;别设真实 Chrome 不会发的 header。Accept-Language 要匹配代理的地理位置:美国住宅 IP 发 en-US,en;q=0.9,德国 IP 发 de-DE,de;q=0.9。这是少数你能免费修好的信号之一。
若目标触发 Managed Challenge(响应体里出现 CF 挑战页),curl_cffi 单独解不了,切到打过补丁的 Chromium + Playwright。
from rebrowser_playwright.sync_api import sync_playwright as rebrowser_sync
with rebrowser_sync() as p:
browser = p.chromium.launch(
headless=True,
proxy={
"server": "http://gate.jibaoproxy.com:10001",
"username": "USERNAME-session-abc123",
"password": "PASSWORD",
},
)
context = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
viewport={"width": 1920, "height": 1080},
locale="en-US",
timezone_id="America/New_York",
)
page = context.new_page()
page.goto("https://target.com/", wait_until="networkidle")
cookies = context.cookies() # cf_clearance 现在在这里
browser.close()
用 rebrowser-playwright 而非原版 playwright,它修补了 Cloudflare 用来识别无头自动化的 CDP 运行时泄露(Runtime.enable 等)。挑战通过后,从 cookie 取出 cf_clearance 交回给 curl_cffi 做真正的抓取循环。浏览器每个会话只需一次,不是每个请求。
在 Cloudflare 保护的站点上,“用最便宜代理”的直觉几乎总是错的。设:HTML 页平均 500KB,共抓 100,000 页,目标启用 Cloudflare Pro + Bot Fight Mode。
| 方案 | 带宽成本 | 成功率 | 每成功请求数 | 总成本 | 每页成本 |
|---|---|---|---|---|---|
| 数据中心 $1/GB + requests | $0.0005/请求 | 0.5% | 200 | $10,000 | $0.10 |
| 数据中心 $1/GB + curl_cffi | $0.0005/请求 | 3% | 33 | $1,650 | $0.0165 |
| 住宅 $6.8/GB + requests | $0.0033/请求 | 40% | 2.5 | $825 | $0.0083 |
| 住宅 $6.8/GB + curl_cffi | $0.0033/请求 | 92% | 1.09 | $360 | $0.0036 |
| 住宅 $6.8/GB + Playwright(rebrowser) | $0.017/请求(含资源+JS) | 96% | 1.04 | $1,700 | $0.017 |
两点值得注意:① 住宅 + curl_cffi 是每成功成本的赢家,比其他组合便宜 3–18 倍 —— 住宅“贵”在 $/GB 上对,在 $/成功页上错。② Playwright 每请求更贵,因为它下载完整资源包;只用它解那一次挑战,然后把 cf_clearance 交给 curl_cffi。
这是我们推荐给规模化抓取 Cloudflare 目标的客户的模式:最小化 Playwright 用量(慢且贵),最大化 curl_cffi 用量(快且便宜)。
from curl_cffi import requests as cf_requests
from rebrowser_playwright.sync_api import sync_playwright
PROXY_USER_FMT = "USERNAME-session-{sid}"
PROXY_HOST = "http://gate.jibaoproxy.com:10001"
PROXY_PASS = "PASSWORD"
def get_cf_clearance(target_url, session_id):
"""一次性 Playwright 调用,解挑战并取出 cf_clearance。"""
with sync_playwright() as p:
browser = p.chromium.launch(
headless=True,
proxy={"server": PROXY_HOST,
"username": PROXY_USER_FMT.format(sid=session_id),
"password": PROXY_PASS},
)
ctx = browser.new_context(user_agent="Mozilla/5.0 ... Chrome/124.0.0.0 Safari/537.36")
page = ctx.new_page()
page.goto(target_url, wait_until="networkidle", timeout=45000)
cookies = ctx.cookies()
browser.close()
return {c["name"]: c["value"] for c in cookies}
def scrape_with_clearance(urls, session_id, cookies):
"""对所有请求复用同一 session_id(sticky IP)。"""
proxy = f"http://{PROXY_USER_FMT.format(sid=session_id)}:{PROXY_PASS}@gate.jibaoproxy.com:10001"
out = []
for url in urls:
r = cf_requests.get(url, impersonate="chrome124",
proxies={"https": proxy}, cookies=cookies, timeout=30)
if r.status_code == 200:
out.append((url, r.text))
elif r.status_code in (403, 503) and "challenge" in r.text.lower():
cookies = get_cf_clearance(url, session_id) # cf_clearance 过期,重解
r = cf_requests.get(url, impersonate="chrome124",
proxies={"https": proxy}, cookies=cookies)
out.append((url, r.text))
return out, cookies
要点:每会话一次 Playwright;sticky 会话 ID 绑定抓取任务(cf_clearance 整个生命周期同一 IP,换 IP 会让 cookie 失效);cf_clearance 过期时响应含挑战页,捕获后重解再继续;impersonate="chrome124" 要与 Playwright 里设的 User-Agent 匹配,UA 与 JA4 不一致本身就是检测信号。
有些 Cloudflare 部署在任何合理成本下都绕不过。看到这些信号就换策略(用 API、与站点方合作、或直接买数据):企业版 Bot Management + Turnstile + 行为追踪(银行、支付、票务、部分体育博彩,成功率即便完美住宅+rebrowser 也不到 5%);叠加自定义 WAF 规则(每住宅 IP 3–5 请求就限速);需要登录 + 2FA + 设备绑定的站点。
| 目标等级 | 配方 | 预期成功率 |
|---|---|---|
| CF 免费/Pro(无 Bot Fight) | 数据中心 + curl_cffi | 60–75% |
| CF 免费/Pro + Bot Fight | 住宅 + curl_cffi | 85–93% |
| CF Business | 住宅 + curl_cffi + 偶尔 Playwright | 80–90% |
| CF Business + Turnstile | 住宅 + rebrowser-playwright(每请求) | 70–85% |
| CF 企业版 + Bot Management | 移动住宅 + rebrowser + 行为模拟 | 30–60% |
| CF 企业版 + Bot Management + 自定义 WAF | 别抓,走 API 或合作 | <10% |
极豹提供动态住宅代理,覆盖 240+ 国家 9000 万+ IP,sticky 会话最长 60 分钟,国家级定向,$6.8/GB 起。移动 IP 见动态移动代理。两者对 curl_cffi、tls-client、Playwright、Puppeteer、Selenium 及任何支持 HTTP/SOCKS5 的客户端开箱即用。
新用户注册即送5U,首次充值额外加赠,活动期间限时开放。