استكشاف الأخطاء

رموز أخطاء CaptchaAI: تشخيص كل خطأ في الـ API وإصلاحه

لا تحتاج إلى حفظ كل رمز خطأ يعيده CaptchaAI؛ يكفي أن تعرف الفئة التي ينتمي إليها الخطأ، لأن الفئة — لا الاسم الحرفي — هي التي تحدد إن كنت ستُصلح الطلب أم تعيد المحاولة أم تتوقف. تعيد واجهة CaptchaAI أخطاءها من نقطتَي نهاية فقط: in.php لحظة إرسال المهمة، وres.php لحظة استطلاع النتيجة، ومعرفة أيّهما أصدر الخطأ تختصر نصف طريق التشخيص.

عند تمرير json=1 في الطلب، تصلك الأخطاء بصيغة JSON:

{"status": 0, "request": "ERROR_CODE_HERE"}

أمّا بدون json=1 فيصلك رمز الخطأ نصاً صريحاً مباشرة: ERROR_CODE_HERE.


صنّف الخطأ أولاً: ست فئات تحدد ردّ فعلك

ضع كل خطأ في إحدى الفئات الست التالية؛ الفئة وحدها تكفي لتقرير الإجراء الصحيح:

فئة الخطأ أمثلة ما تفعله
مصادقة وحساب ERROR_WRONG_USER_KEY، ERROR_KEY_DOES_NOT_EXIST، IP_BANNED أوقف الإرسال، صحّح بيانات الاعتماد، ولا تُعد المحاولة آلياً
انشغال الخيوط أو الرصيد ERROR_ZERO_BALANCE انتظر تحرّر خيط تنفيذ أو ارفع خطتك، ثم أعد الإرسال
معلمات وتنسيق ERROR_PAGEURL، ERROR_WRONG_GOOGLEKEY، ERROR_BAD_TOKEN_OR_PAGEURL، ERROR_BAD_PARAMETERS أصلح الطلب أولاً؛ إعادة إرسال الطلب نفسه بلا فائدة
أخطاء عابرة من الخادم ERROR_SERVER_ERROR، ERROR_INTERNAL_SERVER_ERROR أعد المحاولة بتراجع أسي من 3 إلى 5 مرات
خاصة بالمهمة ERROR_CAPTCHA_UNSOLVABLE، ERROR_PROXY_CONNECTION_FAILED أرسل مهمة جديدة بمعلمات محدّثة، لا نفس المعرّف
استطلاع النتيجة CAPCHA_NOT_READY ليست خطأً؛ واصل الاستطلاع كل 5 ثوانٍ حتى المهلة

أخطاء المصادقة والحساب

تظهر قبل أن يبدأ الحل، وتعني رفض الطلب لسبب في المفتاح أو الحساب أو الخيوط المتاحة، والعلاج إصلاح بيانات الاعتماد لا تكرار الطلب.

ERROR_WRONG_USER_KEY

السبب: قيمة المعلمة key بتنسيق غير صحيح. مفاتيح CaptchaAI API تتكوّن من 32 حرفاً بالضبط.

الإصلاح:

  1. تحقّق أن طول المفتاح 32 حرفاً تماماً.
  2. تأكّد من خلوّه من أي مسافات زائدة أو فواصل أسطر.
  3. انسخ المفتاح مباشرةً من لوحة مفاتيح الـ API دون أي تعديل يدوي.

مثال على مفتاح خاطئ يحمل مسافة زائدة في نهايته:

{
  "key": "abc123... "
}

والصيغة الصحيحة لمفتاح مكتمل بلا مسافات:

{
  "key": "abc12345678901234567890123456789a"
}

ERROR_KEY_DOES_NOT_EXIST

السبب: مفتاح الـ API لا يطابق أي حساب مسجّل في النظام.

الإصلاح:

  1. سجّل الدخول إلى captchaai.com وانسخ المفتاح من لوحة التحكم مجدداً.
  2. تأكّد من أنك تستخدم مفتاح الحساب الصحيح، لا مفتاح حساب اختباري قديم.
  3. إن كنت قد أنشأت الحساب للتو، فامنح المفتاح بضع دقائق حتى يُفعَّل قبل أول طلب.

ERROR_ZERO_BALANCE

السبب: لا يتوفّر في حسابك خيط تنفيذ (thread) حرّ لاستقبال المهمة. لاحظ أن هذا لا يعني بالضرورة نفاد الرصيد.

الإصلاح:

  1. انتظر حتى تنتهي المهام قيد التشغيل، فيتحرّر خيط جديد.
  2. ارفع خطتك للحصول على عدد أكبر من الخيوط المتزامنة.
  3. تحقّق من حالة حسابك عبر صفحة الـ API.

ليس هذا دائماً خطأ "نفاد رصيد". قد يعني ببساطة أن كل خيوطك مشغولة الآن؛ فإن كنت على خطة بخيط واحد ومهمة قيد التنفيذ، ستُعيد كل عمليات الإرسال الجديدة هذا الرمز حتى تكتمل المهمة الأولى.

IP_BANNED

السبب: حُظر عنوان IP الخاص بك مؤقتاً بعد محاولات مصادقة فاشلة متكرّرة.

الإصلاح: انتظر نحو 5 دقائق ثم أعد المحاولة ببيانات الاعتماد الصحيحة. لا تستمر في إرسال الطلبات بمفاتيح API خاطئة، فذلك يطيل الحظر.


أخطاء المعلمات ومفتاح الموقع

الطلب وصل بالفعل، لكنه يحمل معلمات ناقصة أو غير متطابقة مع الصفحة المستهدفة؛ والحل تصحيحه لا تكراره كما هو.

ERROR_PAGEURL

السبب: المعلمة pageurl مفقودة أو فارغة. هذه المعلمة إلزامية لكل اختبارات CAPTCHA المبنية على الرمز مثل reCAPTCHA وCloudflare Turnstile وGeeTest.

الإصلاح: مرّر العنوان الكامل للصفحة التي يُحمَّل عليها اختبار CAPTCHA، متضمناً البروتوكول. قيمة خاطئة (فارغة):

{
  "pageurl": ""
}

قيمة صحيحة تحمل البروتوكول والمسار كاملاً:

{
  "pageurl": "https://example.com/login"
}

ERROR_WRONG_GOOGLEKEY / ERROR_GOOGLEKEY

السبب: قيمة googlekey (مفتاح الموقع) فارغة أو مشوّهة أو مفقودة.

الإصلاح:

  1. أعد استخراج مفتاح الموقع من السمة data-sitekey في الصفحة المستهدفة، أو من المعلمة k في رابط reCAPTCHA.
  2. تأكّد من أن القيمة غير فارغة وغير مقطوعة قبل الإرسال.

مفتاح موقع فارغ يسبّب الخطأ:

{
  "googlekey": ""
}

ومفتاح موقع صحيح بالطول المتوقّع:

{
  "googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
}

ERROR_BAD_TOKEN_OR_PAGEURL

السبب: تركيبة googlekey (مفتاح الموقع) مع pageurl غير صالحة؛ أي أن مفتاح الموقع غير مسجّل لعنوان الصفحة الذي أرسلته.

الأسباب الشائعة:

  • عنصر reCAPTCHA مُحمَّل داخل إطار iframe على نطاق فرعي مختلف، وأنت تمرّر عنوان الصفحة الأم بدل عنوان الـ iframe.
  • مفتاح الموقع يخصّ صفحة أو نطاقاً آخر.
  • استُخرج مفتاح الموقع من بيئة تطوير أو staging لا من صفحة الإنتاج.

الإصلاح:

  1. إن كان reCAPTCHA داخل iframe، فاستخدم عنوان src الخاص بالـ iframe قيمةً لـ pageurl.
  2. تحقّق من مفتاح الموقع من صفحة الإنتاج المباشرة نفسها.
  3. اختبر القيمتين معاً بتحميل رابط reCAPTCHA يدوياً: https://www.google.com/recaptcha/api2/anchor?k=YOUR_SITEKEY

ERROR_BAD_PARAMETERS

السبب: معلمات إلزامية مفقودة أو بأنواع بيانات خاطئة.

الإصلاح: راجع وثائق الـ API الخاصة بنوع الاختبار الذي تحلّه، وتأكّد من وجود كل المعلمات المطلوبة له:

نوع التحقق المعلمات المطلوبة
reCAPTCHA v2/v3 key، method=userrecaptcha، googlekey، pageurl
Cloudflare Turnstile key، method=turnstile، sitekey، pageurl
Cloudflare Challenge key، method=cloudflare_challenge، pageurl، proxy، proxytype
GeeTest v3 key، method=geetest، gt، challenge، pageurl
BLS key، method=bls، body، textinstructions
عادي/صورة key، method=post، file أو body

أخطاء الخادم العابرة

الفئة الوحيدة التي تستحق إعادة المحاولة الآلية، لأن سببها مؤقت من جانب الخادم لا من طلبك.

ERROR_SERVER_ERROR / ERROR_INTERNAL_SERVER_ERROR

السبب: خطأ عابر من جانب الخادم.

الإصلاح: انتظر 10 ثوانٍ ثم أعد المحاولة، مع تراجع أسي في حال تكرّر الفشل:

import time

retry_delay = 10
for attempt in range(5):
    response = submit_captcha()
    if response.get("status") == 1:
        break
    time.sleep(retry_delay)
    retry_delay *= 2  # 10s, 20s, 40s, 80s, 160s

أخطاء الصور والملفات المرفوعة

تخصّ اختبارات الصور ورفع الملفات؛ سببها غالباً حجم أو تنسيق أو ترميز غير سليم، وتُصلَح بتعديل الملف قبل إعادة الإرسال.

ERROR_TOO_BIG_CAPTCHA_FILESIZE

السبب: حجم الصورة المرسلة أكبر من الحد الأقصى المسموح به.

الإصلاح: اضغط الصورة أو صغّر أبعادها قبل الإرسال. استخدم JPEG للصور الفوتوغرافية وPNG للقطات الشاشة.

ERROR_ZERO_CAPTCHA_FILESIZE

السبب: ملف الصورة أصغر من اللازم (أقل من 100 بايت)، ما يشير إلى تحميل فارغ أو تالف.

الإصلاح: تأكّد من أنك ترسل بيانات صورة فعلية، لا ملفاً فارغاً ولا سلسلة Base64 مقطوعة.

ERROR_WRONG_FILE_EXTENSION

السبب: امتداد الملف المرسل غير مدعوم. الامتدادات المدعومة: jpg وjpeg وpng وgif.

الإصلاح: حوّل الصورة إلى أحد التنسيقات المدعومة قبل التحميل.

ERROR_IMAGE_TYPE_NOT_SUPPORTED

السبب: تعذّر على الخادم تحديد نوع الصورة من محتوى الملف نفسه.

الإصلاح: حوّل الصورة إلى تنسيق قياسي (PNG أو JPEG) وتأكّد من سلامتها.

ERROR_UPLOAD

السبب: لم يتمكّن الخادم من قراءة الملف المرفوع أو حمولة Base64.

الإصلاح:

  1. عند رفع ملف: راجع ترميز بيانات النموذج متعدد الأجزاء (multipart).
  2. عند إرسال base64: تأكّد من اكتمال السلسلة وصحّة ترميزها.
  3. جرّب صورة معروفة السلامة لاستبعاد تلف الملف.

أخطاء الوسيط (Proxy)

ترتبط بالخادم الوسيط الذي تمرّره، وتظهر عند الإرسال أو أثناء محاولة الوصول إلى الموقع المستهدف عبره.

ERROR_BAD_PROXY

السبب: الخادم الوسيط الذي مرّرته غير قابل للوصول، أو صنّفه النظام على أنه رديء.

الإصلاح:

  1. اختبر الوسيط بمعزل عن CaptchaAI — هل يصل فعلاً إلى الموقع المستهدف؟
  2. جرّب وسيطاً مختلفاً.
  3. تحقّق من التنسيق: login:password@IP:PORT أو IP:PORT للوسطاء المصادَق عليهم بعنوان IP.

استخدام الوسيط يجب أن يكون مفعّلاً على حسابك أولاً؛ تواصل مع دعم CaptchaAI إن لم تفعّله بعد.

ERROR_PROXY_CONNECTION_FAILED

السبب: تعذّر على الخدمة الوصول إلى الموقع المستهدف عبر الوسيط الخاص بك.

الإصلاح:

  1. قد يكون الوسيط معطّلاً مؤقتاً — جرّب خادماً آخر.
  2. قد يكون الموقع المستهدف يحظر عنوان IP للوسيط.
  3. تأكّد من أن الوسيط قادر فعلاً على الوصول إلى الموقع المستهدف.

أخطاء استطلاع النتيجة على res.php

تظهر عند الاستفسار عن حالة مهمة أرسلتها، ومعظمها لا يستدعي القلق ما دمت تستطلع بالمعرّف الصحيح.

CAPCHA_NOT_READY

هذا ليس خطأً. إنه يعني أن الحل ما زال قيد التنفيذ.

الإجراء: انتظر 5 ثوانٍ ثم استطلع النتيجة مجدداً.

if result.get("request") == "CAPCHA_NOT_READY":
    time.sleep(5)
    continue  # poll again

دليل التوقيت المقترح لأول استطلاع:

نوع التحقق أول استطلاع بعد فاصل الاستطلاع
reCAPTCHA v2/v3/Enterprise 15 ثانية 5 ثوانٍ
Cloudflare Turnstile 15 ثانية 5 ثوانٍ
Cloudflare Challenge 20 ثانية 5 ثوانٍ
GeeTest v3 15 ثانية 5 ثوانٍ
عادي/صورة 5 ثوانٍ 5 ثوانٍ

ERROR_EMPTY_ACTION

السبب: المعلمة action مفقودة أو فارغة في طلب الاستطلاع.

الإصلاح: أضف action=get إلى طلب res.php:

params = {
    "key": api_key,
    "action": "get",  # Required
    "id": captcha_id,
    "json": 1,
}

ERROR_CAPTCHA_UNSOLVABLE

السبب: لم يتمكّن CaptchaAI من حل الاختبار بعد عدة محاولات.

الأسباب الشائعة:

  1. نوع CAPTCHA غير مدعوم أو المعلمات خاطئة.
  2. التحدي تالف أو منتهي الصلاحية.
  3. في الحلول المعتمدة على وسيط: الوسيط بطيء جداً أو متعذّر الوصول.
  4. غيّر الموقع طريقة تطبيقه لاختبار CAPTCHA.

الإصلاح:

  1. تحقّق من صحة معلماتك (مفتاح الموقع، عنوان الصفحة، الطريقة).
  2. أعد الإرسال بطلب جديد.
  3. إن كنت تستخدم وسيطاً، فجرّب وسيطاً مختلفاً.
  4. إن استمر الخطأ، فقد يكون الموقع قد تغيّر — أعد استخراج مفتاح الموقع وعنوان الصفحة.

لا تعِد المحاولة بنفس معرّف المهمة. أرسل مهمة جديدة بمعلمات محدّثة.

ERROR_WRONG_ID_FORMAT

السبب: معرّف الاختبار يجب أن يكون رقمياً فقط.

الإصلاح: تأكّد من أنك ترسل المعرّف الدقيق الذي أعاده in.php (أرقام فقط، دون أي أحرف إضافية).

ERROR_WRONG_CAPTCHA_ID

السبب: معرّف المهمة غير موجود أو انتهت صلاحيته.

الإصلاح:

  1. تأكّد من أنك تستطلع بالمعرّف الذي أعاده إرسالك، لا بمعرّف آخر.
  2. قد تنتهي صلاحية المعرّفات بعد فترات طويلة — أعد الإرسال إن كانت المهمة قديمة جداً.

ملاحظة: قد يظهر ERROR_WRONG_USER_KEY وERROR_KEY_DOES_NOT_EXIST على res.php بنفس سبب وإصلاح فئة المصادقة أعلاه.


سيناريو واقعي: ‏ERROR_ZERO_BALANCE أثناء ذروة الجمعة البيضاء

تخيّل فريق بيانات في القاهرة يراقب أسعار المنافسين قبيل الجمعة البيضاء. مع ارتفاع وتيرة جمع البيانات، بدأت طلبات الإرسال تُعيد ERROR_ZERO_BALANCE رغم أن الرصيد الشهري لم ينفد. السبب أن الفريق على خطة BASIC ($15 شهرياً، 5 خيوط)، وكانت الخيوط الخمسة جميعها مشغولة، فلم يبقَ خيط حرّ للمهمة الجديدة.

الحل ليس شراء رصيد، لأن CaptchaAI يحاسب على أساس الخيوط المتزامنة لا على كل عملية حل، مع حلول غير محدودة لكل خيط. أمام الفريق خياران: قائمة انتظار مع تراجع أسي حتى يتحرّر خيط، أو الترقية إلى خطة أعلى مثل ADVANCE ($90 شهرياً، 50 خيطاً) قبل الذروة. القاعدة: عامِل ERROR_ZERO_BALANCE إشارةَ تزامن قبل أن تعامله إشارةَ رصيد.


قالب جاهز لمعالجة أخطاء CaptchaAI

انسخ النمط التالي لتغليف الإرسال والاستطلاع بمعالجة أخطاء متينة؛ فهو يفصل الأخطاء التي تُصلَح مرة واحدة عن القابلة لإعادة المحاولة، ويطبّق التراجع الأسي تلقائياً.

بايثون

import time
import requests

API_KEY = "YOUR_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"

# Errors that should not be retried (fix the request first)
NO_RETRY_ERRORS = {
    "ERROR_WRONG_USER_KEY",
    "ERROR_KEY_DOES_NOT_EXIST",
    "ERROR_PAGEURL",
    "ERROR_WRONG_GOOGLEKEY",
    "ERROR_GOOGLEKEY",
    "ERROR_BAD_TOKEN_OR_PAGEURL",
    "ERROR_BAD_PARAMETERS",
    "ERROR_WRONG_FILE_EXTENSION",
    "ERROR_IMAGE_TYPE_NOT_SUPPORTED",
    "IP_BANNED",
}

# Errors that can be retried
RETRY_ERRORS = {
    "ERROR_ZERO_BALANCE",
    "ERROR_SERVER_ERROR",
    "ERROR_INTERNAL_SERVER_ERROR",
    "ERROR_UPLOAD",
}


def solve_captcha(submit_data, max_retries=3, max_polls=60):
    """Submit and solve a CAPTCHA with full error handling."""

    # Submit with retry logic
    for attempt in range(max_retries):
        resp = requests.post(SUBMIT_URL, data={**submit_data, "json": 1}, timeout=30)
        resp.raise_for_status()
        data = resp.json()

        if data.get("status") == 1:
            captcha_id = data["request"]
            break

        error = data.get("request", "UNKNOWN")

        if error in NO_RETRY_ERRORS:
            raise ValueError(f"Fatal error (fix request): {error}")

        if error in RETRY_ERRORS and attempt < max_retries - 1:
            time.sleep(10 * (2 ** attempt))
            continue

        raise RuntimeError(f"Submit failed: {error}")
    else:
        raise RuntimeError("Submit failed after max retries")

    # Poll for result
    time.sleep(15)

    for _ in range(max_polls):
        resp = requests.get(
            RESULT_URL,
            params={"key": API_KEY, "action": "get", "id": captcha_id, "json": 1},
            timeout=30,
        )
        data = resp.json()

        if data.get("request") == "CAPCHA_NOT_READY":
            time.sleep(5)
            continue

        if data.get("status") == 1:
            return data["request"]

        error = data.get("request", "UNKNOWN")
        if error == "ERROR_CAPTCHA_UNSOLVABLE":
            raise RuntimeError("CAPTCHA unsolvable — resubmit with fresh parameters")

        raise RuntimeError(f"Poll error: {error}")

    raise TimeoutError("Solve timed out")

Node.js

const NO_RETRY_ERRORS = new Set([
  "ERROR_WRONG_USER_KEY",
  "ERROR_KEY_DOES_NOT_EXIST",
  "ERROR_PAGEURL",
  "ERROR_WRONG_GOOGLEKEY",
  "ERROR_BAD_TOKEN_OR_PAGEURL",
  "ERROR_BAD_PARAMETERS",
  "IP_BANNED",
]);

async function solveCaptcha(submitData, maxRetries = 3, maxPolls = 60) {
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

  // Submit with retry
  let captchaId;
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const resp = await fetch("https://ocr.captchaai.com/in.php", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams({ ...submitData, json: "1" }),
    });
    const data = await resp.json();

    if (data.status === 1) {
      captchaId = data.request;
      break;
    }

    if (NO_RETRY_ERRORS.has(data.request)) {
      throw new Error(`Fatal error: ${data.request}`);
    }

    if (attempt < maxRetries - 1) {
      await sleep(10_000 * 2 ** attempt);
      continue;
    }

    throw new Error(`Submit failed: ${data.request}`);
  }

  // Poll for result
  await sleep(15_000);

  for (let i = 0; i < maxPolls; i++) {
    const resp = await fetch(
      `https://ocr.captchaai.com/res.php?${new URLSearchParams({
        key: submitData.key,
        action: "get",
        id: captchaId,
        json: "1",
      })}`
    );
    const data = await resp.json();

    if (data.request === "CAPCHA_NOT_READY") {
      await sleep(5_000);
      continue;
    }

    if (data.status === 1) return data.request;

    throw new Error(`Poll error: ${data.request}`);
  }

  throw new Error("Solve timed out");
}

أسئلة شائعة حول رموز أخطاء CaptchaAI

ما الفرق بين ERROR_ZERO_BALANCE ونفاد الرصيد فعلياً؟

ERROR_ZERO_BALANCE يعني غياب خيط تنفيذ حرّ في اللحظة الحالية، وقد يحدث مع رصيد كامل إذا كانت كل خيوطك مشغولة. إن كانت كلها قيد الاستخدام فالمشكلة تزامن لا رصيد، والحل الانتظار حتى يتحرّر خيط أو الترقية لخطة بخيوط أكثر.

لماذا يظهر ERROR_BAD_TOKEN_OR_PAGEURL رغم أن مفتاح الموقع صحيح؟

غالباً لأن reCAPTCHA مُحمَّل داخل iframe على نطاق فرعي مختلف، فتمرّر عنوان الصفحة الأم بدل عنوان الـ iframe. استخدم عنوان src الخاص بالـ iframe قيمةً لـ pageurl، وتأكّد أن المفتاح من صفحة الإنتاج.

متى أتوقف عن استطلاع res.php وأعتبر المهمة فاشلة؟

ابدأ أول استطلاع بعد الفاصل المذكور في جدول التوقيت، ثم كل 5 ثوانٍ. اضبط حداً أقصى للمحاولات (مثلاً 60) واعتبر المهمة منتهية المهلة بعده، بدل استطلاع لانهائي يستهلك الخيوط.

هل أعيد استخدام نفس معرّف المهمة بعد ERROR_CAPTCHA_UNSOLVABLE؟

لا. أرسل مهمة جديدة بمعلمات محدّثة، فالمعرّف السابق مرتبط بمحاولة فاشلة نهائياً. إن تكرّر، فراجع مفتاح الموقع وعنوان الصفحة وتأكّد أن نوع الاختبار مدعوم.

كيف أتحقق من رصيدي وعدد الخيوط المتاحة؟

سجّل الدخول إلى لوحة التحكم ثم افتح صفحة الـ API، حيث يظهر رصيدك وحالة خيوطك. راجعها قبل موجات الإرسال الكبيرة لتتجنّب مفاجأة ERROR_ZERO_BALANCE وقت الذروة.


أدلة ذات صلة

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