自动化脚本连上一个 Cloudflare 站点,到底会遇到什么——是要填一个验证码挂件,还是直接被网络层拦下来?答案取决于两个经常被混为一谈的产品。Turnstile 是任何网站都能免费嵌入的验证码挂件,只保护你提交的那一个表单;Bot Management 则是 Cloudflare 企业版才有的网络级防御,对域名下的每一次请求都要打分。
分不清这两者,是调试自动化脚本时最常见的误判来源。本文按实际遇到的现象,把判定方法、集成方式和 CaptchaAI 的处理方案捋清楚。
先分清楚:你到底遇到的是哪个产品
基本定位
| 维度 | Bot Management | Turnstile |
|---|---|---|
| 本质 | 企业级机器人防护平台 | 免费验证码挂件 |
| 定价 | 仅企业版可用,价格面议 | 所有套餐免费 |
| 部署位置 | 网络层(Cloudflare 代理) | 页面级 JavaScript 挂件 |
| 是否要求接入 Cloudflare DNS | 是 | 否,任何网站都能嵌入 |
检测与执行细节
| 维度 | Bot Management | Turnstile |
|---|---|---|
| 可见挑战 | 有时(Managed Challenge) | 很少,大多数情况下无感 |
| 检测范围 | 域名下的每一次请求 | 具体的页面动作(如表单提交) |
| 机器人分数 | 1–99,按请求计算 | 无分数,按次通过 / 不通过 |
| WAF 联动 | 支持(按分数触发规则) | 不支持 |
| JavaScript 挑战 | 支持(5 秒等待页) | 支持(后台工作量证明) |
| 限流 | 支持 | 不支持 |
| CaptchaAI 支持 | 通过 Turnstile / Challenge 方法处理挑战组件 | 支持,识别成功率高 |
从现象倒推:脚本卡在哪一步
先看脚本卡在什么现象上,基本能倒推出背后是哪个产品:
- 5 秒等待页 —— Bot Management 的 JS 挑战(
jschl_vc)。 - 表单上的 Turnstile 挂件 —— Turnstile 独立产品(
cf-turnstileclass)。 - 403 + Cloudflare 错误页模板 —— Bot Management 硬拦截(
cf-ray)。 - 交互式复选框 —— Managed Challenge,属于 Bot Management。
- 无可见挑战但 cf cookie 已写入 —— Bot Management 判定已通过。
403 不一定是验证码问题,也可能是纯网络层拦截,拿不准就用后面的脚本确认。
Cloudflare Bot Management:网络层怎么给你打分
Bot Management 只有 Cloudflare 企业版才能用,运行在网络层——域名下的每一次请求,在到达源站之前都会先被评估一遍。它看的是请求头、TLS 指纹和历史行为拼在一起的综合信号,而不是单个页面动作,所以遇到 Bot Management 通常比只遇到 Turnstile 更棘手。
打分逻辑
Request arrives at Cloudflare edge
↓
Bot Management engine evaluates:
├─ Machine learning model (behavioral fingerprint)
├─ Heuristics (known bot patterns)
├─ JavaScript fingerprinting (if JS challenge triggered)
├─ JA3/JA4 TLS fingerprint
├─ HTTP header analysis
└─ IP reputation (Cloudflare sees ~20% of internet traffic)
↓
Bot score assigned: 1 (definitely bot) to 99 (definitely human)
↓
WAF rules act on the score:
- Score > 50 → Allow
- Score 30-50 → Managed challenge
- Score < 30 → Block or JavaScript challenge
六个核心组件
- 机器人分数:基于机器学习模型,给每一次请求打分。
- Managed Challenge:自适应展示 JS 挑战或 Turnstile 挂件。
- Super Bot Fight Mode:非企业版 Cloudflare 用户可用的简化版机器人防护(对应 Pro、Business)。
- Bot Analytics:展示机器人流量与真实用户流量对比的看板。
- WAF 自定义规则:按机器人分数阈值触发的规则。
- 限流:按 IP / 会话设置的请求速率阈值。
- JavaScript 检测:识别无头浏览器和自动化工具。
自动化脚本会看到什么
站点一旦启用 Bot Management,自动化请求可能撞上以下四种情况之一:
- 直接 403 —— 机器人分数很低,WAF 规则直接拦截
- JavaScript 挑战页 —— 经典的 5 秒“检查您的浏览器”等待页
- Managed Challenge —— 渲染成 Turnstile 挂件,或纯 JS 挑战
- 无感放行 —— 机器人分数够高,请求直接通过
Cloudflare Turnstile:挂在页面上的免费验证码
Turnstile 是一个独立的验证码挂件,用来替代传统验证码。它不依赖 Bot Management 运行,任何网站都能免费嵌入——不只是接入了 Cloudflare 代理的站点。
后台都做了什么
Page loads Turnstile widget
↓
Widget runs background checks:
├─ Browser proof-of-work challenge (cryptographic puzzle)
├─ Private Access Token (Apple devices)
├─ Browser environment validation
└─ Cloudflare threat intelligence
↓
Result: cf-turnstile-response token generated
↓
Token submitted with form data
↓
Server validates token via Cloudflare API (siteverify)
三种模式,Managed 默认就够用
- Managed —— 自动在无感和交互式之间切换,默认推荐。
- Non-interactive —— 始终无感,只做后台工作量证明,适合低摩擦表单。
- Invisible —— 完全看不到挂件,加载时在后台运行,适合纯背景校验。
集成只要两行代码
<!-- Simple Turnstile integration -->
<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQhMMQ_Rxrg"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
用 CaptchaAI 分别处理
举个例子:一个做海外电商库存监控的团队,目标站点的结账表单挂了 Turnstile,脚本要在提交前先拿到 token。
如果目标站同时开了 Bot Management,光解出 token 还不够,请求本身也得先在网络层通过打分。50 个并发任务的量级,ADVANCE 套餐($90/月,50 线程)通常够用。
先确认目标是 Turnstile 挂件还是 Bot Management 的网络层判定——两者对应不同的 CaptchaAI 方法。
Turnstile:识别成功率高
通过 CaptchaAI 的
turnstile方法处理:
import requests
import time
API_KEY = "YOUR_API_KEY"
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "0x4AAAAAAAC3DHQhMMQ_Rxrg",
"pageurl": "https://example.com/signup",
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
token = result["request"]
print(f"Turnstile token: {token[:50]}...")
break
Bot Management 的 Managed Challenge
- Bot Management 本身是多层防御叠加的结果,验证码只是其中一层。
- 若出现验证码组件,通常渲染成 Turnstile 样式的 Managed Challenge,可用 Turnstile 方法处理:
# Bot Management flow for automation:
# 1. Make initial request
response = requests.get("https://protected-site.com/api/data")
# 2. Check if challenged
if response.status_code == 403:
# Hard block — need to adjust headers, proxy, or approach
pass
elif "challenge" in response.text.lower() or response.status_code == 503:
# JavaScript challenge or managed challenge
# If it contains a Turnstile widget, solve it:
if "cf-turnstile" in response.text or "challenges.cloudflare.com" in response.text:
# Extract sitekey and solve via CaptchaAI
sitekey = extract_turnstile_sitekey(response.text)
token = solve_turnstile(sitekey, "https://protected-site.com/api/data")
Cloudflare Challenge 页面(不是 Turnstile)
这不是 Turnstile 挂件,是等待页本身;CaptchaAI 通过
cloudflare_challenge方法单独处理:
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "cloudflare_challenge",
"sitekey": "managed",
"pageurl": "https://protected-site.com/login",
"json": 1,
})
用代码自动识别,不用每次肉眼判断
批量跑站点时更适合直接用代码判定,而不是逐个肉眼检查:
import requests
def identify_cloudflare_protection(url):
"""Identify which Cloudflare protection a URL uses."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0",
}
response = requests.get(url, headers=headers, timeout=15, allow_redirects=False)
html = response.text
result = {
"cloudflare_protected": "cf-ray" in response.headers.get("cf-ray", "")
or "cloudflare" in response.headers.get("server", "").lower(),
"bot_management_challenge": False,
"turnstile_widget": False,
"hard_block": False,
"passed": False,
}
if response.status_code == 403:
result["hard_block"] = True
elif response.status_code == 503 and "jschl" in html:
result["bot_management_challenge"] = True
elif "cf-turnstile" in html:
result["turnstile_widget"] = True
elif response.status_code == 200:
result["passed"] = True
return result
常见问题
Bot Management 和 Turnstile 能同时挂在同一个网站上吗?
能,而且很常见。Bot Management 在网络层对所有请求打分,Turnstile 挂在具体页面上,两者互不冲突。典型组合:边缘用 Bot Management 拦掉明显的机器人流量,登录 / 注册表单再单独加一层 Turnstile。
为什么请求没被直接拦截,却跳出了 Managed Challenge?
机器人分数落在中间地带(通常 30–50 分),WAF 没有直接放行也没有直接拦截,交给 Managed Challenge 二次判断——这一步经常渲染成 Turnstile 挂件,用 Turnstile 方法即可识别。
页面上完全看不到 Turnstile 挂件,是不是没生效?
不一定。Managed 和 Invisible 模式本来就不展示交互式界面,只在后台做工作量证明,无感通过是正常行为。可在浏览器控制台确认 cf-turnstile-response 是否已生成。
CaptchaAI 能同时处理 Turnstile 和 Cloudflare Challenge 页面吗?
能。Turnstile 走 turnstile 方法;5 秒等待页走 cloudflare_challenge 方法。两者是不同的 API 调用,脚本里最好先判断页面类型,再选对应方法提交。
403 Forbidden 是不是意味着 CaptchaAI 帮不上忙?
分情况。403 页面里带验证码组件,CaptchaAI 能处理;但若是网络层硬拦截、页面上没有任何验证码可解,问题出在请求头、TLS 指纹或 IP 信誉上,需要先调整这些再重试——CaptchaAI 只覆盖验证码识别,不负责网络层放行判定。
一句话总结
Cloudflare Bot Management 是企业版才有的网络层防御,用机器学习打分、WAF 规则和行为分析评估每一次请求;Cloudflare Turnstile 是免费的验证码挂件,靠浏览器工作量证明验证用户。做自动化时,Turnstile 直接用 CaptchaAI 识别,成功率高;Bot Management 的挑战则要先把浏览器模拟做对,验证码组件部分再交给 CaptchaAI 处理。