脚本请求一个网站,返回永远是 HTTP 503,页面上一行“正在检查您的浏览器”,还卡着大约 5 秒——这基本可以断定,你撞上了 Cloudflare 的“我受到攻击”模式(IUAM,俗称“5 秒盾”)。这是 Cloudflare 最激进的防护等级,运营者遭遇 DDoS 攻击时手动开启,也有站点长期挂着。不管真人还是脚本,都得先跑完一段 JavaScript 计算才能进站,requests、axios、cURL 这类纯 HTTP 客户端做不到,因为它们不执行 JavaScript。
解法: 用
cloudflare_challenge方法解出挑战,带着qa_session_cookie和同一个 IP、User-Agent 继续请求,完整代码见下文。
IUAM(Cloudflare 攻击模式)到底做了什么
打开“我处于攻击模式”开关后,访问链路变成这样:
Every request → Cloudflare edge
↓
JavaScript challenge page served (HTTP 503)
↓
Browser executes JavaScript challenge (~5 seconds)
↓
Challenge answer submitted automatically
↓
qa_session_cookie cookie set
↓
Original page loaded with qa_session_cookie cookie
挑战页面里都有什么
IUAM 挑战页返回 HTTP 503,含:
jschl_vc——挑战验证码pass——计时令牌,强制 5 秒等待jschl_answer——JavaScript 计算出的答案cf_chl_opt——挑战选项ray——本次请求的 Cloudflare Ray ID- “正在检查您的浏览器……”——展示给用户看的提示文案
一眼认出 IUAM 的几个特征
- 状态码是 503,不是 403
- 提交答案前必须等满 5 秒,跳不过去
- 必须执行 JavaScript —— 纯 HTTP 客户端一律失败
qa_session_cookiecookie 有效期约 30 分钟,拿到后才能继续访问- 域名级生效 —— 站点下每个页面都会被拦下来
怎么判断撞上的是 IUAM,还是别的 Cloudflare 防护
Cloudflare 的防护档位不止 IUAM 一种,Managed Challenge、Turnstile、WAF 拦截返回的现象都不一样。下面这段脚本按状态码和页面特征逐层判断:
import requests
def identify_cloudflare_protection(url):
"""Distinguish IUAM from other Cloudflare protections."""
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
status = response.status_code
if status == 503 and "jschl" in html:
return "IUAM (I'm Under Attack Mode)"
if status == 503 and "challenge-platform" in html:
return "Managed Challenge"
if status == 403 and "cf-ray" in str(response.headers):
return "Blocked by WAF/Bot Management"
if "cf-turnstile" in html:
return "Turnstile widget"
if "challenges.cloudflare.com" in html:
return "Cloudflare 验证流程 (generic)"
if status == 200:
return "No challenge (passed)"
return f"Unknown (status: {status})"
四种防护的对照表
| 信号 | IUAM | Managed Challenge | Turnstile | WAF 拦截 |
|---|---|---|---|---|
| HTTP 状态码 | 503 | 503 | 200 | 403 |
正文含 jschl |
✅ | ❌ | ❌ | ❌ |
| 强制 5 秒等待 | ✅ | 有时 | ❌ | ❌ |
qa_session_cookie 会写入 |
解决后 | 解决后 | ❌ | ❌ |
| 挑战页范围 | 整页 | 整页 | 仅小部件 | 错误页 |
| 需要执行 JS | ✅ | ✅ | ✅ | ❌ |
那道 JavaScript 挑战到底在算什么
IUAM 的 JavaScript 挑战本质是在验证“这是不是一个真实浏览器”:
挑战的六个步骤
- Cloudflare 下发挑战页,代码经过混淆
- 浏览器执行计算:对字符串做数学运算、做 DOM 测量、强制计时至少 4-5 秒
- 算出答案 —— 基于挑战内容推导出的数值
- 自动把
jschl_vc、pass、jschl_answer打包成表单提交给 Cloudflare - Cloudflare 校验答案和耗时是否合理
- 校验通过后下发
qa_session_cookiecookie —— 约 30 分钟内可正常访问
纯 HTTP 客户端为什么注定过不去
# This will ALWAYS get the challenge page:
import requests
response = requests.get("https://iuam-protected-site.com")
# response.status_code == 503
# response.text contains "Checking your browser..."
# Plain HTTP clients cannot:
# - Execute JavaScript
# - Compute the challenge answer
# - Meet the timing requirement
# - Generate the required cookies
用 CaptchaAI 自动解出 IUAM 挑战
举个例子:跨境电商价格监控脚本,目标站点大促期间临时开了 IUAM,请求从 200 变成清一色 503。不用改抓取逻辑,请求前插一次挑战求解,把 qa_session_cookie 带进后续请求即可。
方法一:cloudflare_challenge 方法(推荐)
CaptchaAI 的 cloudflare_challenge 方法直接处理 IUAM 挑战,不需要额外搭浏览器环境:
import requests
import time
API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://iuam-protected-site.com/data"
# Step 1: Submit challenge to CaptchaAI
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "cloudflare_challenge",
"sitekey": "managed",
"pageurl": TARGET_URL,
"json": 1,
})
task_id = submit.json()["request"]
print(f"Task submitted: {task_id}")
# Step 2: Poll for result
for attempt 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"Challenge solved! Token: {token[:50]}...")
break
elif result.get("request") == "ERROR_CAPTCHA_UNSOLVABLE":
print("Challenge could not be solved")
break
else:
print("Timed out waiting for solution")
# Step 3: Use qa_session_cookie cookie or token
# The response contains the clearance data needed to access the site
cloudflare_challenge 通常在 15 秒内完成识别,成功率较高——具体数值以实测为准。
以下数字基于公开资料与内部观测样本,仅供参考。实际结果会因运行环境、任务量和时间而不同,请在自有环境中测量。
方法二:无头浏览器 + CaptchaAI,适合长会话
需要维持较长会话(不只拿一次 cookie)时,把无头浏览器和 CaptchaAI 组合起来更合适:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time
API_KEY = "YOUR_API_KEY"
# Launch browser
options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=options)
# Navigate to IUAM page
driver.get("https://iuam-protected-site.com")
# Wait for challenge page to load
time.sleep(3)
# Check if IUAM challenge is present
if "Checking your browser" in driver.page_source or driver.title == "Just a moment...":
print("IUAM challenge detected")
# Option A: Wait for browser to solve natively (if not headless)
try:
WebDriverWait(driver, 15).until(
lambda d: "Checking your browser" not in d.page_source
)
print("Challenge passed natively")
except:
print("Native solve failed — using CaptchaAI")
# Submit to CaptchaAI for solving
# Token submission via JavaScript injection
# After challenge is passed, extract cookies for API use
cookies = driver.get_cookies()
qa_session_cookie = next(
(c["value"] for c in cookies if c["name"] == "qa_session_cookie"), None
)
if qa_session_cookie:
print(f"qa_session_cookie obtained: {qa_session_cookie[:30]}...")
# Use cookie with requests library
session = requests.Session()
for cookie in cookies:
session.cookies.set(cookie["name"], cookie["value"])
session.headers.update({
"User-Agent": driver.execute_script("return navigator.userAgent"),
})
# Now make requests with the clearance cookie
response = session.get("https://iuam-protected-site.com/api/data")
print(f"Status: {response.status_code}")
driver.quit()
方法一的 Node.js 版本
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const TARGET_URL = "https://iuam-protected-site.com/data";
async function solveIUAM() {
// Submit challenge
const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: {
key: API_KEY,
method: "cloudflare_challenge",
sitekey: "managed",
pageurl: TARGET_URL,
json: 1,
},
});
const taskId = submit.data.request;
console.log(`Task submitted: ${taskId}`);
// Poll for result
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId, json: 1 },
});
if (result.data.status === 1) {
console.log("IUAM challenge solved!");
return result.data.request;
}
}
throw new Error("Timed out");
}
solveIUAM().then((token) => console.log("Token:", token.substring(0, 50)));
常见故障排查
最常见的几种情况:
- 挑战循环解不完——IP 变了,解题和访问要用同一个 IP
qa_session_cookie被拒绝——User-Agent 不一致,两边保持一致- 解完还是 503——cookie 已过期(超过 30 分钟),提前刷新
- 挑战页面不一样——实际是 Managed Challenge,换成 Turnstile 方法
- 撞见多个挑战页——先 IUAM 后 Turnstile,依次解决
qa_session_cookie 怎么管理
解出 IUAM 挑战之后,真正有用的产出就是这个 qa_session_cookie:
- Cookie 名称——
qa_session_cookie - 有效期——约 30 分钟(站点可自行配置)
- 作用范围——整个域名
- 绑定条件——IP 地址 + User-Agent
- 能否复用——能,在有效期内可反复使用
- 能否转移——只有 IP + UA 都一致时才行
一个可以直接抄的 Cookie 管理策略
import requests
import time
class IUAMSessionManager:
"""Manage qa_session_cookie cookies for IUAM-protected sites."""
def __init__(self, api_key, target_url, user_agent=None):
self.api_key = api_key
self.target_url = target_url
self.user_agent = user_agent or (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0"
)
self.session = requests.Session()
self.session.headers["User-Agent"] = self.user_agent
self.clearance_time = 0
self.clearance_lifetime = 1800 # 30 minutes default
def needs_refresh(self):
"""Check if clearance cookie needs refreshing."""
return time.time() - self.clearance_time > self.clearance_lifetime - 60
def solve_challenge(self):
"""Solve IUAM challenge and update session cookies."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key,
"method": "cloudflare_challenge",
"sitekey": "managed",
"pageurl": self.target_url,
"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": self.api_key,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
# Apply clearance to session
self.clearance_time = time.time()
return result["request"]
raise TimeoutError("IUAM solve timed out")
def get(self, url, **kwargs):
"""Make a GET request, solving IUAM if needed."""
if self.needs_refresh():
self.solve_challenge()
return self.session.get(url, **kwargs)
常见问题
接入时最常被问到:
用 CaptchaAI 解一次 IUAM 大概要多久?
cloudflare_challenge 通常 15 秒内出结果,比图片、网格验证码(通常不到 1 秒)慢,因为要模拟浏览器完成计时计算,轮询间隔建议设在 5 秒左右。
qa_session_cookie 能用多久,要不要提前刷新?
默认约 30 分钟,站点也可配置成 15 分钟到 24 小时,多数用默认值。建议在有效期快到前主动刷新,而不是等失效再补救。
解题时提示 ERROR_CAPTCHA_UNSOLVABLE,是哪里出了问题?
先确认站点真的是 IUAM,而不是已切成 Managed Challenge 或 Turnstile——挑战类型变了自然解不出来。其次检查 pageurl 是否和实际请求地址一致。
Cloudflare 攻击模式是不是一直开着?
不是。多数是运营者遇攻击时临时打开,也有站点长期挂着当额外防护,今天没有不代表明天也没有。
GeeTest、reCAPTCHA 这些验证会不会和 IUAM 出现在同一条链路里?
会。IUAM 只挡在域名入口,站内登录、下单页可能另挂 reCAPTCHA v2/v3、Turnstile 或 GeeTest v3,需按顺序解决:先过 IUAM 拿 qa_session_cookie,再解页面内的验证码。
一句话总结
- 域名下所有请求清一色 503、页面提示"正在检查您的浏览器",基本可以断定是 Cloudflare 攻击模式(IUAM)
- 用 CaptchaAI 的 Cloudflare 验证流程 求解器(
cloudflare_challenge方法)解出挑战,即可拿到qa_session_cookie - 拿到 cookie 后 30 分钟内可直接复用,但全程要保持同一个 IP 和 User-Agent