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 处理。

相关文章

该文章已禁用评论。