Comparisons

Cloudflare Bot Management 与 Turnstile:了解差异

自动化脚本连上一个 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-turnstile class)。
  • 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 处理。

相关文章

该文章已禁用评论。