Сообщество Forex трейдеров
Форум трейдеров => Валютный рынок FOREX => Тема начата: omocaptchaHem от 22.01.2026 15:01:03 pm
-
Cloudflare Turnstile识别:API接入指å—
Cloudflare Turnstileè¯†åˆ«çš„æ ¸å¿ƒï¼Œå…¶å®žå°±æ˜¯æ‹¿åˆ°ä¸€ä¸ª cf-turnstile-response token å¹¶å›žå¡«åˆ°ç›®æ ‡è¡¨å•里。本文用 OMOCaptcha çš„ API V2 演示完整æµç¨‹ï¼šè¯»å–页é¢ä¸Šçš„ Turnstile sitekey(以 0x... å¼€å¤´ï¼‰å’Œé¡µé¢ URL,调用 createTask 创建任务,å†è½®è¯¢ getTaskResult å–出 token。全程附带å¯ç›´æŽ¥å¤åˆ¶è¿è¡Œçš„ Python 与 Node.js 代ç ï¼Œå¸®ä½ åœ¨è‡ªåŠ¨åŒ–æµ‹è¯•ã€ç›‘控ç‰åˆæ³•场景ä¸å®Œæˆ turnstile 识别。
什么是 Cloudflare Turnstile
Turnstile 是 Cloudflare 推出的éšç§ä¼˜å…ˆã€é€šå¸¸æ— 感(invisible)的人机验è¯ç»„ä»¶ï¼Œç”¨æ¥æ›¿ä»£ä¼ 统 CAPTCHA。它在åŽå°è¯„ä¼°æµè§ˆå™¨ä¿¡å·ï¼Œå¤šæ•°æƒ…å†µä¸‹æ— éœ€ç”¨æˆ·ç‚¹å‡»å›¾ç‰‡æˆ–æ‹¼å›¾ï¼Œåªåœ¨å¿…è¦æ—¶å¼¹å‡ºäº¤äº’æŒ‘æˆ˜ã€‚ä½ å¯ä»¥åœ¨ Cloudflare 官方文档 (https://developers.cloudflare.com/turnstile/) 查阅其嵌入方å¼ã€‚
需è¦ç‰¹åˆ«åŒºåˆ†ä¸¤ä¸ªæ¦‚念:
- Turnstile token:页é¢é‡Œ <div class="cf-turnstile" data-sitekey="0x..."> 组件生æˆçš„一次性å‡è¯ï¼Œè¡¨å•æäº¤æ—¶é€šè¿‡éšè—å—æ®µ cf-turnstile-response 上é€ï¼ŒæœåŠ¡ç«¯ç”¨ siteverify æ ¡éªŒã€‚æœ¬æ–‡è®²çš„ cloudflare 验è¯ç 识别,指的就是获å–这个 token。
- Cloudflare 全站拦截挑战(interstitial challenge):那是站点级的 WAF 拦截页,产出的是 cf_clearance 之类的挑战 Cookie,属于å¦ä¸€å¥—机制,和 Turnstile token 䏿˜¯ä¸€å›žäº‹ã€‚
æžæ¸…楚这一点很é‡è¦ï¼šTurnstile 识别产出的是 tokenï¼Œä½ è¦æŠŠå®ƒæ”¾å›žè¡¨å•å—æ®µï¼›è€Œå…¨ç«™æŒ‘æˆ˜è¿”å›žçš„æ˜¯ä¼šè¯ Cookie。二者ä¸è¦æ··æ·†ã€‚
识别æµç¨‹æ€»è§ˆ
Turnstile 识别是典型的「token 型验è¯ç ã€æµç¨‹ï¼Œå’Œ reCAPTCHA 识别 (https://blog.omocaptcha.com/ruhe-shibie-recaptcha) 与 hCaptcha 识别 (https://blog.omocaptcha.com/ruhe-shibie-hcaptcha) 完全一致:
1. åœ¨ç›®æ ‡é¡µé¢ä¸Šæ‰¾åˆ° Turnstile çš„ sitekey(data-sitekey,以 0x 开头)和 é¡µé¢ URL。
2. 调用 POST /createTask,任务类型用 Turnstile token 任务,æºå¸¦ websiteURL 与 websiteKey。
3. 轮询 POST /getTaskResult,直到 status å˜ä¸º ready。
4. 从 solution 读出 token,回填到页é¢çš„ cf-turnstile-response å—æ®µå¹¶æäº¤è¡¨å•。
所有接å£åŸºå€ä¸º https://api.omocaptcha.com/v2,HTTP 状æ€ç æ’为 200,æˆåŠŸä¸Žå¦ç”± errorId(0 表示æˆåŠŸï¼‰åˆ¤æ–,采用与 AntiCaptcha 兼容的错误信å°ã€‚
注æ„:下方代ç 使用的任务类型å—符串为 TurnstileTokenTask。这是éžç¡®è®¤ç±»åž‹ï¼Œè¯·ä»¥ OMOCaptcha API 文档 (https://omocaptcha.com/zh?utm_source=blog&utm_medium=organic) ä¸çš„确切 type 为准。已确认å¯ç”¨çš„类型包括 ImageToTextTask 与 RecaptchaV2TokenTask。
Python 完整示例
import requests
import time
CLIENT_KEY = "YOUR_API_KEY"
BASE = "https://api.omocaptcha.com/v2"
def solve_turnstile(website_url, website_key):
# 1. 创建任务
create = requests.post(
f"(BASE)/createTask",
json=(
"clientKey": CLIENT_KEY,
"task": (
"type": "TurnstileTokenTask", # 请在 OMOCaptcha 文档确认确切 type
"websiteURL": website_url,
"websiteKey": website_key,
),
),
timeout=30,
).json()
if create.get("errorId") != 0:
raise RuntimeError(f"createTask 失败: (create.get('errorCode')) - (create.get('errorDescription'))")
task_id = create["taskId"]
# 2. 轮询结果,带退é¿
delay = 3
for _ in range(20):
time.sleep(delay)
res = requests.post(
f"(BASE)/getTaskResult",
json=("clientKey": CLIENT_KEY, "taskId": task_id),
timeout=30,
).json()
if res.get("errorId") != 0:
raise RuntimeError(f"getTaskResult 失败: (res.get('errorCode'))")
status = res.get("status")
if status == "ready":
# Turnstile token 通常在 solution.token
return res["solution"].get("token") or res["solution"].get("gRecaptchaResponse")
if status == "fail":
raise RuntimeError("任务失败")
delay = min(delay + 2, 10) # 礼貌退é¿
raise TimeoutError("轮询超时")
if __name__ == "__main__":
token = solve_turnstile("https://example.com/login", "0xAAAAAAAAAAAAAAAAAA")
print("cf-turnstile-response =", token)
拿到 token åŽï¼ŒæŠŠå®ƒå†™å…¥é¡µé¢çš„éšè—å—æ®µå†æäº¤ï¼š
# 例如é…åˆ Selenium/Playwright 回填
# driver.execute_script(
# "document.querySelector('[name=cf-turnstile-response]').value = arguments[0];",
# token,
# )
Node.js 完整示例
const CLIENT_KEY = "YOUR_API_KEY";
const BASE = "https://api.omocaptcha.com/v2";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function postJson(path, body) (
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 30000); // 30s è¶…æ—¶
try (
const resp = await fetch(`$(BASE)$(path)`, (
method: "POST",
headers: ( "Content-Type": "application/json" ),
body: JSON.stringify(body),
signal: controller.signal,
));
return await resp.json();
) finally (
clearTimeout(timer);
)
)
async function solveTurnstile(websiteURL, websiteKey) (
// 1. 创建任务
const create = await postJson("/createTask", (
clientKey: CLIENT_KEY,
task: (
type: "TurnstileTokenTask", // 请在 OMOCaptcha 文档确认确切 type
websiteURL,
websiteKey,
),
));
if (create.errorId !== 0) (
throw new Error(`createTask 失败: $(create.errorCode)`);
)
const taskId = create.taskId;
// 2. 轮询,带退é¿
let delay = 3000;
for (let i = 0; i < 20; i++) (
await sleep(delay);
const res = await postJson("/getTaskResult", ( clientKey: CLIENT_KEY, taskId ));
if (res.errorId !== 0) throw new Error(`getTaskResult 失败: $(res.errorCode)`);
if (res.status === "ready") (
return res.solution.token • • res.solution.gRecaptchaResponse;
)
if (res.status === "fail") throw new Error("任务失败");
delay = Math.min(delay + 2000, 10000);
)
throw new Error("轮询超时");
)
solveTurnstile("https://example.com/login", "0xAAAAAAAAAAAAAAAAAA")
.then((token) => console.log("cf-turnstile-response =", token))
.catch(console.error);
ä»·æ ¼ä¸Žå…¶å®ƒéªŒè¯ç
Turnstile 属于 OMOCaptcha 支æŒçš„ 14 ç§éªŒè¯ç 之一,从 from $0.27/1000 èµ·æ¥ã€‚一个 createTask 端点å³å¯è¦†ç›– reCAPTCHAã€hCaptchaã€FunCaptchaã€GeeTest (https://blog.omocaptcha.com/geetest-jiyan-shibie) ç‰å¤šç§ç±»åž‹ï¼Œæ— 需为æ¯ç§éªŒè¯ç åˆ‡æ¢æœåŠ¡å•†ã€‚
验è¯ç 类型 • ä»·æ ¼ï¼ˆæ¯ 1000 次)
reCAPTCHA v2 • $0.27
FunCaptcha (Arkose) • $0.27
Cloudflare Turnstile • 支æŒ
hCaptcha • $0.60
GeeTest • $0.60
完整清å•è§ ä»·æ ¼é¡µ (https://omocaptcha.com/zh#pricing)。想横å‘对比,å¯å‚考验è¯ç 识别 API ä»·æ ¼ (https://blog.omocaptcha.com/yanzhengma-shibie-api-jiage)与最佳验è¯ç 识别æœåŠ¡æŽ¨è (https://blog.omocaptcha.com/yanzhengma-shibie-fuwu-tuijian)。
OMOCaptcha 采用纯 AI æ±‚è§£ï¼ˆæ— äººå·¥æ‰“ç é˜Ÿåˆ—å»¶è¿Ÿï¼‰ï¼Œå¹³å‡ 0.42 秒返回ã€å‡†ç¡®çŽ‡é«˜è¾¾ 99%,比国际竞å“便宜约 20–40%,并æä¾›æˆåŠŸçŽ‡ä½ŽäºŽ 95% å…¨é¢é€€æ¬¾çš„ SLAã€‚è‹¥ä½ æ£åœ¨ä»Ž 2Captcha è¿ç§»ï¼Œä¹Ÿå¯ä»¥çœ‹çœ‹ 2Captcha 替代方案 (https://blog.omocaptcha.com/2captcha-tidai-fangan)。
åˆç†ä½¿ç”¨æé†’
请仅将 turnstile è¯†åˆ«ç”¨äºŽåˆæ³•è‡ªåŠ¨åŒ–åœºæ™¯ï¼šå¯¹ä½ è‡ªå·±ç½‘ç«™è¡¨å•çš„ QA 与回归测试ã€å¯è®¿é—®æ€§ã€ç»æŽˆæƒ/å—åˆåŒçº¦æŸçš„æ•°æ®é‡‡é›†ã€è´Ÿè½½æµ‹è¯•与监控ç‰ã€‚务必éµå®ˆç›®æ ‡ç«™ç‚¹çš„ robots.txtã€æœåŠ¡æ¡æ¬¾ä¸Žé€Ÿçއé™åˆ¶ã€‚è¯·å‹¿ç”¨äºŽæ‰¹é‡æ³¨å†Œè™šå‡è´¦å·ã€æ¬ºè¯ˆæˆ–è§„é¿å°ç¦ç‰è¡Œä¸ºã€‚关于在åˆè§„剿䏋é™ä½Žè¢«æ‹¦æˆªæ¦‚率,å¯å‚考网页采集ä¸è¢«å°é” (https://blog.omocaptcha.com/wangye-caiji-bu-bei-fengsuo)。
æ³¨æ„æœ¬æ–‡æ‰€è¿°æ˜¯æ ‡å‡†çš„ turnstile token èŽ·å–æ–¹å¼ï¼Œå±žäºŽæ£è§„çš„ API 集æˆï¼Œè€Œéžæ¼æ´žå¼çš„ turnstile 绕过;产出的 token ä»éœ€ç»æœåŠ¡ç«¯æ£å¸¸æ ¡éªŒã€‚
FAQ
Turnstile token 和 Cloudflare 挑战 Cookie 有什么区别?
Turnstile token 是 cf-turnstile-response å—æ®µçš„一次性å‡è¯ï¼Œç”¨äºŽè¡¨å•æäº¤æ—¶çš„äººæœºæ ¡éªŒï¼›è€Œ cf_clearance ç‰æ˜¯å…¨ç«™æ‹¦æˆªæŒ‘æˆ˜äº§ç”Ÿçš„ä¼šè¯ Cookie。本文的 cloudflare 验è¯ç 识别针对的是å‰è€…。
sitekey 在哪里找?
æŸ¥çœ‹é¡µé¢ HTML ä¸ class="cf-turnstile" çš„å…ƒç´ ï¼Œå…¶ data-sitekey 属性值å³ä¸º sitekey,通常以 0x 开头。把它连åŒé¡µé¢ URL ä¼ å…¥ createTask å³å¯ã€‚
token 有有效期å—?
有。Turnstile token 是一次性且有时效的,建议获å–åŽå°½å¿«å›žå¡«å¹¶æäº¤è¡¨å•,ä¸è¦é•¿æœŸç¼“å˜ã€‚
任务类型å—ç¬¦ä¸²å†™é”™äº†ä¼šæ€Žæ ·ï¼Ÿ
createTask ä¼šè¿”å›žéž 0 çš„ errorId 与对应 errorCode。请以 OMOCaptcha 官方 API 文档ä¸çš„确切 type 为准;已确认的类型有 ImageToTextTask å’Œ RecaptchaV2TokenTask。
我的数æ®å®‰å…¨å—?
OMOCaptcha é‡‡ç”¨ç«¯åˆ°ç«¯åŠ å¯†ï¼Œä¸å˜å‚¨éªŒè¯ç 内容ã€ä¸è®°å½•客户数æ®ã€‚任务与创建它的 API key 绑定(key-binding),用错 key 会返回 ERROR_TASK_KEY_MISMATCH。
ç«‹å³å¼€å§‹ Cloudflare Turnstile识别
注册å³é€ 1000 次å…费识别,用上é¢çš„代ç å‡ åˆ†é’Ÿå°±èƒ½è·‘é€š turnstile 识别。é‡åˆ°é—®é¢˜æ¬¢è¿Žé‚®ä»¶è”ç³» support@omocaptcha.com,7x24 å°æ—¶å“应。
å‰å¾€ OMOCaptcha 官网 (https://omocaptcha.com/zh?utm_source=blog&utm_medium=organic) 领å–å…è´¹é¢åº¦ï¼Œç”¨ä¸€ä¸ª API æžå®š Cloudflare Turnstile åŠå…¶å®ƒ 14 ç§éªŒè¯ç 。想快速上手å¯çœ‹éªŒè¯ç API 快速上手 (https://blog.omocaptcha.com/yanzhengma-api-kuaisu-shangshou)。