دروس API

حل Cloudflare Turnstile باستخدام CaptchaAI API

Cloudflare Turnstile بديل للكابتشا يركّز على الخصوصية ويعمل بصمت في الخلفية. على عكس الكابتشا التقليدية، نادراً ما يعرض تحدياً مرئياً؛ بل يجمع إشارات المتصفح ويُصدر رمزاً (token) يتحقق منه الخادم الخلفي للموقع.

يوضح هذا الدليل كيف تحلّ Turnstile برمجياً عبر واجهة CaptchaAI. إن لم تقرأ بعدُ دليل البدء السريع لـ CaptchaAI فابدأ به لفهم تدفّق الخطوات الأربع العام.


المتطلبات

العنصر القيمة
مفتاح CaptchaAI API من لوحة التحكم على captchaai.com
sitekey الخاص بـ Turnstile يُستخرج من الصفحة (يبدأ بـ 0x)
رابط الصفحة الرابط الكامل الذي يظهر فيه Turnstile
اللغة Python 3.7+ أو Node.js 14+

الخطوة 1: استخرج sitekey

عادةً يوجد sitekey داخل HTML الصفحة، ضمن وسم div أو script:

<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQFLr1GavNl"></div>

أو يُرسم عبر JavaScript:

turnstile.render('#widget', {
  sitekey: '0x4AAAAAAAC3DHQFLr1GavNl',
  callback: function(token) { /* ... */ }
});

ثلاث طرق للاستخراج:

  1. أدوات المطور: تبويب Elements، ابحث عن data-sitekey أو cf-turnstile.
  2. شيفرة المصدر: Ctrl+U، ثم ابحث عن سلاسل تبدأ بـ 0x.
  3. تبويب Network: فلتر بـ challenges.cloudflare.com؛ يظهر sitekey ضمن وسائط الطلب.

sitekey الخاص بـ Turnstile يبدأ دائماً بـ 0x وطوله غالباً 22 محرفاً، مما يميّزه عن مفاتيح reCAPTCHA التي تبدأ بـ 6L.


الخطوة 2: أرسل المهمة

أرسل طلب 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–25 ثانية. انتظر 10 ثوانٍ ثم استطلع كل 5 ثوانٍ بحدّ أقصى 40 محاولة:

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 محرف.


الخطوة 4: احقن الرمز في الصفحة

ضع الرمز داخل الحقل المخفي 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"))

الأخطاء الشائعة

الكود المعنى الإجراء
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.


حين لا يعمل

  1. sitekey ديناميكي. بعض مواقع Cloudflare تُصدر sitekey جديداً مع كل زيارة؛ أعد جلب الصفحة قبل كل مهمة.
  2. pageurl دقيق. يقارن خادم Turnstile الرابط بصرامة؛ أرسل المسار الفعلي بدون معاملات الاستعلام.
  3. بصمة TLS. قد ترفض Cloudflare العميل بناءً على بصمة TLS. استعن بـ curl_cffi أو Playwright أو متصفح حقيقي.
  4. انتهاء صلاحية الرمز. استخدم الرمز خلال دقيقتين وإلا ستحتاج إلى إعادة الحل.
  5. جودة البروكسي. عناوين IP الرخيصة لمراكز البيانات تستفز تحديات إضافية؛ يُفضّل البروكسي السكني أو الجوّال.

الخطوات التالية

أدلة ذات صلة

التعليقات غير مفعّلة لهذا المقال.