تحلّ Cloudflare Turnstile برمجياً عبر أربع خطوات يمرّ بها هذا الدليل واحدة تلو الأخرى مع أمثلة Python وNode.js جاهزة للنسخ:
- استخرج مفتاح الموقع (sitekey) من صفحة الهدف.
- أرسل المهمة إلى CaptchaAI مع مفتاح الموقع ورابط الصفحة.
- استطلع النتيجة حتى يجهز الرمز.
- أدرج الرمز في النموذج قبل إرساله.
على عكس الكابتشا التقليدية التي تعرض صوراً أو ألغازاً، يعمل Turnstile بصمت في الخلفية: يجمع إشارات المتصفح ويُصدر رمزاً (token) يتحقق منه خادم الموقع. لهذا لا يوجد ما «تنقر» عليه؛ ما تحتاجه فعلياً هو الحصول على رمز صالح وإدراجه في الطلب. إن لم تطّلع بعد على التدفّق العام، فابدأ من دليل البدء السريع لـ CaptchaAI.
ما تحتاجه لحلّ Turnstile
قبل كتابة أيّ سطر، جهّز العناصر الأربعة التالية:
| العنصر | القيمة |
|---|---|
| مفتاح CaptchaAI API | من لوحة التحكم على captchaai.com |
| مفتاح الموقع (sitekey) لـ Turnstile | يُستخرج من الصفحة، ويبدأ بـ 0x |
| رابط الصفحة | الرابط الكامل الذي يظهر فيه Turnstile |
| بيئة التشغيل | Python 3.7+ أو Node.js 14+ |
الخطوة 1: استخرج مفتاح موقع Turnstile
يوجد مفتاح الموقع عادةً داخل HTML الصفحة، ضمن وسم div يحمل الصنف cf-turnstile:
<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQFLr1GavNl"></div>
أو يُرسَم ديناميكياً عبر JavaScript:
turnstile.render('#widget', {
sitekey: '0x4AAAAAAAC3DHQFLr1GavNl',
callback: function(token) { /* ... */ }
});
ثلاث طرق سريعة للعثور عليه:
- أدوات المطوّر: افتح تبويب Elements وابحث عن
data-sitekeyأوcf-turnstile. - شيفرة المصدر: اضغط
Ctrl+Uثم ابحث عن سلسلة تبدأ بـ0x. - تبويب Network: فلتر على
challenges.cloudflare.com؛ يظهر المفتاح ضمن وسائط الطلب.
يبدأ مفتاح Turnstile دائماً بـ
0xوطوله غالباً 22 محرفاً، ما يميّزه عن مفاتيح reCAPTCHA التي تبدأ بـ6L.
الخطوة 2: أرسل المهمة إلى CaptchaAI
أرسل طلب POST إلى نقطة النهاية https://ocr.captchaai.com/in.php مع تعيين method=turnstile وتمرير مفتاح الموقع ورابط الصفحة:
import requests
API_KEY = "YOUR_CAPTCHAAI_KEY"
SITEKEY = "0x4AAAAAAAC3DHQFLr1GavNl"
PAGEURL = "https://example.com/login"
r = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": SITEKEY,
"pageurl": PAGEURL,
"json": 1,
})
data = r.json()
if data["status"] != 1:
raise RuntimeError(f"submit failed: {data}")
task_id = data["request"]
print("task id:", task_id)
ونفس المنطق بـ Node.js:
const axios = require("axios");
const { data } = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: {
key: process.env.CAPTCHAAI_KEY,
method: "turnstile",
sitekey: "0x4AAAAAAAC3DHQFLr1GavNl",
pageurl: "https://example.com/login",
json: 1,
},
});
if (data.status !== 1) throw new Error(`submit failed: ${JSON.stringify(data)}`);
const taskId = data.request;
عند النجاح تعود الاستجابة بالشكل {"status": 1, "request": "<task_id>"}. احفظ قيمة task_id؛ ستستخدمها في خطوة الاستطلاع.
الخطوة 3: استطلع النتيجة حتى يجهز الرمز
يُنجَز حل Turnstile عادةً في أقل من 10 ثوانٍ مع معدل نجاح مرتفع. امنح الخادم مهلة أولية قصيرة، ثم استطلع النتيجة كل 5 ثوانٍ حتى يجهز الرمز أو تنفد المحاولات:
import time
time.sleep(10)
for _ in range(40):
r = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
})
res = r.json()
if res["status"] == 1:
token = res["request"]
break
if res["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(f"solver error: {res}")
time.sleep(5)
else:
raise TimeoutError("turnstile solving timed out")
print("token (أوّل 60 محرفاً):", token[:60])
الرمز المُعاد سلسلة Base64 تبدأ غالباً بمقدّمة من الأصفار متبوعة بنقطة، ويتراوح طولها بين 400 و600 محرف. تذكّر أن CAPCHA_NOT_READY ليست خطأً؛ إنها تعني ببساطة أن الحل ما زال جارياً.
الخطوة 4: أدرج رمز Turnstile في النموذج
ابحث عن الحقل المخفي cf-turnstile-response داخل نموذج Turnstile، اضبط قيمته على الرمز، ثم أرسل النموذج. اختر الأسلوب المناسب لأداتك:
عبر Selenium:
driver.execute_script(
"document.querySelector('[name=cf-turnstile-response]').value = arguments[0];",
token,
)
driver.find_element("css selector", "form").submit()
عبر Playwright:
page.evaluate(
"(t) => document.querySelector('[name=cf-turnstile-response]').value = t",
token,
)
page.click("button[type=submit]")
عبر طلب HTTP خام: أضف cf-turnstile-response=<token> إلى جسم الطلب بترميز application/x-www-form-urlencoded.
صلاحية رمز Turnstile قصيرة — عادةً بين 120 و300 ثانية. استخدمه فور استلامه، وإلا أعاد الخادم الخطأ
timeout-or-duplicate.
مثال Python كامل
تجمع الدالة التالية الخطوات الأربع في وظيفة واحدة قابلة لإعادة الاستخدام: تقرأ المفتاح من متغيّر بيئة، ترسل المهمة، تستطلع النتيجة، وتعيد الرمز الجاهز.
import os, time, requests
API = "https://ocr.captchaai.com"
KEY = os.environ["CAPTCHAAI_KEY"]
def solve_turnstile(sitekey: str, pageurl: str) -> str:
r = requests.post(f"{API}/in.php", data={
"key": KEY, "method": "turnstile",
"sitekey": sitekey, "pageurl": pageurl, "json": 1,
}, timeout=30)
j = r.json()
if j["status"] != 1:
raise RuntimeError(f"submit: {j}")
tid = j["request"]
time.sleep(10)
for _ in range(40):
r = requests.get(f"{API}/res.php", params={
"key": KEY, "action": "get", "id": tid, "json": 1,
}, timeout=30)
j = r.json()
if j["status"] == 1:
return j["request"]
if j["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(f"poll: {j}")
time.sleep(5)
raise TimeoutError("timeout")
if __name__ == "__main__":
print(solve_turnstile("0x4AAAAAAAC3DHQFLr1GavNl", "https://example.com/login"))
سيناريو عملي: أتمتة اختبارات QA لمنصة إقليمية
لنفترض أنك في فريق هندسي لمتجر إلكتروني في منطقة الخليج، وتبني مجموعة اختبارات QA آلية تتحقّق يومياً من مسار تسجيل الدخول وإتمام الشراء. صفحة الدخول محمية بـ Turnstile، ولا تستطيع خطوة الاختبار المتابعة دون رمز صالح. بدل تعطيل الحماية في بيئة الاختبار، تستدعي الدالة أعلاه للحصول على رمز حقيقي وإكمال التدفّق تماماً كما يراه المستخدم النهائي.
لأن حل Turnstile يستغرق أقل من 10 ثوانٍ، يكفي عدد صغير من الـ Threads لتغطية أحجام يومية كبيرة. وتعتمد الفوترة في CaptchaAI على عدد الـ Threads المتزامنة لا على كل عملية حل، مع حلول غير محدودة داخل الخطة الواحدة:
- خطة BASIC — 15 دولاراً شهرياً بخمسة Threads، تكفي لمجموعة اختبارات صغيرة تعمل ليلاً.
- خطة ADVANCE — 90 دولاراً شهرياً بخمسين Thread، لمسارات CI/CD المكثّفة أو التشغيل المتوازي عبر عدة بيئات.
بهذا تبقى التكلفة الشهرية متوقّعة بدل الدفع مقابل كل عملية حل.
الأخطاء الشائعة ومعالجتها
| الكود | المعنى | الإجراء |
|---|---|---|
ERROR_WRONG_USER_KEY |
تنسيق المفتاح غير صحيح | تأكد من اكتمال CAPTCHAAI_KEY |
ERROR_KEY_DOES_NOT_EXIST |
المفتاح غير موجود | انسخه من جديد من لوحة التحكم |
ERROR_ZERO_BALANCE |
الرصيد صفر | اشحن الحساب وأعد المحاولة |
ERROR_PAGEURL |
وسيط pageurl ناقص | أرسل الرابط الكامل مع https:// |
ERROR_CAPTCHA_UNSOLVABLE |
فشل الحل بعد عدة محاولات | تحقق من تطابق sitekey وpageurl وأعد المحاولة |
للاطّلاع على جدول رموز الأخطاء الكامل، راجع دليل حل reCAPTCHA v2 عبر API.
عندما يفشل حلّ Turnstile رغم صحّة الشيفرة
- مفتاح موقع متغيّر. بعض صفحات Cloudflare تُصدر مفتاحاً جديداً مع كل زيارة؛ أعد جلب الصفحة قبل كل مهمة بدل تخزين المفتاح.
- رابط صفحة غير مطابق. يقارن خادم Turnstile الرابط بصرامة؛ أرسل المسار الفعلي دون معاملات الاستعلام الزائدة.
- بصمة TLS. قد يرفض Cloudflare العميل بناءً على بصمة TLS؛ استعن بمكتبة مثل
curl_cffiأو بمتصفح حقيقي عبر Playwright. - رمز منتهي الصلاحية. أدرج الرمز خلال دقائق من استلامه، وإلا فستحتاج إلى إعادة الحل.
- جودة البروكسي. عناوين IP الرخيصة لمراكز البيانات قد تستفزّ تحديات إضافية؛ يُفضّل الخادم الوسيط السكني أو الجوّال.
أسئلة شائعة
هل حلّ Cloudflare Turnstile عبر API قانوني؟
نعم، طالما كان الاستخدام مشروعاً: اختبارات QA على أنظمتك، أو الأتمتة والمراقبة على مواقع تملك إذناً بالوصول إليها، أو استخراج بيانات متاحة للعموم ضمن شروط الموقع. الأداة تحلّ التحقق المطلوب فقط، وتبقى مسؤولية مشروعية سير العمل على عاتق المستخدم.
أيّ خطة تناسب حجم طلباتي؟
تعتمد الفوترة على عدد الـ Threads المتزامنة لا على عدد عمليات الحل. للتجارب والمشاريع الصغيرة تكفي خطة BASIC (15 دولاراً شهرياً، خمسة Threads). أما مسارات CI/CD المكثّفة أو جمع البيانات على نطاق واسع فتناسبها خطة ADVANCE (90 دولاراً شهرياً، خمسون Thread) وما فوقها، وجميع الخطط تشمل حلولاً غير محدودة داخل الشهر.
هل يحلّ CaptchaAI أنواع كابتشا أخرى إلى جانب Turnstile؟
نعم؛ يدعم reCAPTCHA v2/v3 وCloudflare Challenge وGeeTest v3 والكابتشا الصورية وشبكات الصور وBLS. أما hCaptcha وFunCaptcha فغير مدعومين حالياً، وGeeTest v4 «قيد الإطلاق» وليس متاحاً بعد. تحقّق من نوع التحدّي قبل بناء التكامل.
لماذا يُرفض الرمز رغم نجاح عملية الحل؟
غالباً بسبب عدم تطابق مفتاح الموقع أو رابط الصفحة مع القيم التي ظهر Turnstile من خلالها، أو لأن الرمز استُهلك أو انتهت صلاحيته قبل إرساله. تأكّد من تطابق sitekey وpageurl، وأرسل الرمز فور استلامه دون تأخير.