Cloudflare 保护了互联网上超过 20% 的网站。如果你在 2026 年构建网页爬虫,你不可避免地会遇到 Cloudflare 保护 — 无论是登录表单上的 Turnstile 小组件、JS Challenge 中间页,还是 WAF 级别的全面 Bot Management。本指南详细介绍每种保护类型,解释最常见的绕过方法,并提供可直接运行的代码示例。
Cloudflare 保护类型
Cloudflare 提供三种主要保护层,你在爬取时会遇到这些保护。了解你面对的是哪种保护是绕过它的第一步。
如何识别保护类型
在选择绕过方法之前,先确定你面对的是什么:
- •Turnstile:查找带有 cf-turnstile 类名的 «div» 或加载 challenges.cloudflare.com/turnstile 的脚本。HTML 源码中会包含 data-sitekey 属性。
- •JS Challenge:你会看到全页面的 "正在检查您的浏览器..." 界面。响应状态码为 403 并设置 __cf_bm Cookie。通过后获得 cf_clearance。
- •Bot Management / WAF:你会立即收到 403 Forbidden,没有挑战页面。或者看到 Cloudflare 的 "拒绝访问" 错误页面。通常基于 IP 信誉或 TLS 指纹。
常见绕过方法对比
有三种主流方法可以绕过 Cloudflare。每种在速度、可靠性和成本方面都有不同的权衡。
| 方法 | 速度 | 可靠性 | 检测风险 | 费用/千次 |
|---|---|---|---|---|
| 无头浏览器 | 5-30秒 | 60-80% | 高 | $2-5 |
| 隐身插件 | 5-20秒 | 70-85% | 中等 | $1-3 |
Solver API推荐 | 0.25-5秒 | 95%+ | 无 | $0.80-1.00 |
何时使用什么方法
不同的保护类型需要不同的方法。以下是快速决策指南:
将 siteKey 和页面 URL 发送到 Solver API。获取有效的 Token 后与表单数据一起提交。无需浏览器 — 仅需普通 HTTP 请求。NSLSolver 在约 250ms 内解决 Turnstile。
Solver 运行 JavaScript 挑战并返回 cf_clearance Cookie 和匹配的 User-Agent 字符串。在后续请求中使用相同的 IP/代理。NSLSolver 在 2-5 秒内返回结果。
WAF 规则检查你的 IP 信誉和 TLS 指纹。使用住宅代理通过 IP 检查,使用 Solver API 处理挑战页面。始终使用 solve 响应中返回的 User-Agent。
使用 NSLSolver 解决 Turnstile
对于 Turnstile 保护的表单,你只需要 siteKey 和页面 URL。API 返回一个你与表单一起提交的 Token:
import requests
API_KEY = "nsl_YOUR_API_KEY"
# 1. Solve the Turnstile widget
solve = requests.post(
"https://api.nslsolver.com/solve",
headers={"X-API-Key": API_KEY},
json={
"type": "turnstile",
"siteKey": "0x4XXXXXXXXXXXXXXXXX",
"url": "https://target-site.com/login"
}
)
token = solve.json()["token"]
# 2. Submit the form with the solved token
result = requests.post(
"https://target-site.com/login",
data={
"username": "[email protected]",
"password": "your_password",
"cf-turnstile-response": token
}
)
print(result.status_code) # 200使用 NSLSolver 解决 CF Challenge
对于 JS Challenge 页面,API 运行浏览器检查并返回 clearance Cookie 和 User-Agent。你必须在同一 IP 上同时使用这些:
import requests
API_KEY = "nsl_YOUR_API_KEY"
# 1. Solve the CF Challenge — returns cookies + user agent
solve = requests.post(
"https://api.nslsolver.com/solve",
headers={"X-API-Key": API_KEY},
json={
"type": "challenge",
"url": "https://target-site.com/protected-page"
}
)
data = solve.json()
# 2. Use the returned cookies and user agent
session = requests.Session()
session.headers["User-Agent"] = data["userAgent"]
for cookie in data["cookies"]:
session.cookies.set(cookie["name"], cookie["value"])
# 3. Access the protected page
page = session.get("https://target-site.com/protected-page")
print(page.status_code) # 200
print(page.text[:500])处理 Bot Management / WAF
当网站使用高级 Bot Management 时,你需要将住宅代理与 Solver API 结合使用。将代理传递给 solve 请求,以便 Cookie 绑定到该 IP:
import requests
API_KEY = "nsl_YOUR_API_KEY"
PROXY = "http://user:[email protected]:8080"
# 1. Solve the challenge through a residential proxy
solve = requests.post(
"https://api.nslsolver.com/solve",
headers={"X-API-Key": API_KEY},
json={
"type": "challenge",
"url": "https://target-site.com/data",
"proxy": PROXY
}
)
data = solve.json()
# 2. Use the same proxy + cookies for subsequent requests
session = requests.Session()
session.proxies = {"http": PROXY, "https": PROXY}
session.headers["User-Agent"] = data["userAgent"]
for cookie in data["cookies"]:
session.cookies.set(cookie["name"], cookie["value"])
page = session.get("https://target-site.com/data")
print(page.json())性能对比:无头浏览器 vs Solver API
运行自己的无头浏览器看起来像是 DIY 方案,但数据说明了不同的故事:
| 指标 | 无头浏览器 | NSLSolver API |
|---|---|---|
| Turnstile 解决时间 | 5-15s | ~250ms |
| Challenge 解决时间 | 10-30s | 2-5s |
| 成功率 | 60-80% | 95%+ |
| 月成本(1万次解决) | $50-200 | $8-10 |
| 维护 | 高 — 需要持续更新 | 无 |
基于 2026 年 4 月的内部基准测试。无头浏览器成本包括服务器、代理和浏览器维护。
成本分析:自建 vs 购买
让我们来分析运行自己的无头浏览器爬虫基础设施与使用 Solver API 的真实成本:
- 4+ GB RAM 的 VPS/云服务器
- 住宅代理带宽
- 浏览器补丁和反检测更新
- 运维人员的维护时间
- 按解决次数付费 — 无固定成本
- 无需维护服务器
- 无需管理代理(Turnstile 类型)
- 注册即送 100 次免费解决
Cloudflare 爬取最佳实践
无论你使用哪种方法,遵循以下做法可以最大化成功率并避免被封:
- •轮换代理:不要通过同一个 IP 发送所有请求。使用住宅代理池,按会话或请求批次轮换。
- •匹配 User-Agent:始终使用 Solver 返回的确切 User-Agent 字符串。Cloudflare 将 cf_clearance Cookie 绑定到解决挑战时使用的 User-Agent。
- •处理速率限制:尊重 429 响应。实现指数退避(1秒、2秒、4秒、8秒)。不要轰炸目标网站 — 将请求分散在一段时间内。
- •添加重试逻辑:瞬态故障是存在的。在放弃之前重试 2-3 次失败的解决请求。上面的生产示例展示了这种模式。
- •重用会话:获取有效 Cookie 后,重复使用它们进行多次请求。cf_clearance Cookie 通常有效期为 15-30 分钟。不要为每个请求都重新解决。
- •注意 TLS 指纹:如果使用自己的 HTTP 客户端,确保其 TLS 指纹与真实浏览器匹配。curl_cffi (Python) 或 got-scraping (Node.js) 等库可以帮助解决这个问题。
生产级爬虫示例
以下是一个完整的 Python 爬虫,支持代理轮换、重试逻辑和会话重用来处理 Cloudflare Challenge 页面:
import requests
import time
import random
API_KEY = "nsl_YOUR_API_KEY"
BASE_URL = "https://api.nslsolver.com/solve"
PROXIES = [
"http://user:[email protected]:8080",
"http://user:[email protected]:8080",
]
def solve_cloudflare(url, solve_type="challenge", retries=3):
"""Solve Cloudflare protection with retry logic."""
for attempt in range(retries):
try:
proxy = random.choice(PROXIES)
resp = requests.post(
BASE_URL,
headers={"X-API-Key": API_KEY},
json={
"type": solve_type,
"url": url,
"proxy": proxy,
},
timeout=30,
)
resp.raise_for_status()
data = resp.json()
if data.get("success"):
return data, proxy
except requests.RequestException as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
return None, None
def scrape_page(url):
"""Scrape a Cloudflare-protected page."""
data, proxy = solve_cloudflare(url)
if not data:
raise Exception("Failed to solve Cloudflare challenge")
session = requests.Session()
session.headers["User-Agent"] = data["userAgent"]
session.proxies = {"http": proxy, "https": proxy}
for cookie in data["cookies"]:
session.cookies.set(cookie["name"], cookie["value"])
response = session.get(url)
response.raise_for_status()
return response.text
# Usage
html = scrape_page("https://target-site.com/data")
print(f"Got {len(html)} bytes")小贴士:cf_clearance Cookie 有效期为 15-30 分钟。在同一域名的请求中缓存并重复使用它们,以避免不必要的解决调用并节省费用。