المرجع

الترحيل من EndCaptcha إلى CaptchaAI: دليل مطابقة الـ API

الانتقال من EndCaptcha إلى CaptchaAI لا يعني إعادة كتابة منطق الحل بالكامل، بل استبدال طبقة الاتصال فقط. أنت تتحوّل من واجهة SOAP/XML تعتمد اسم مستخدم وكلمة مرور إلى واجهة REST بسيطة عبر نقطتَي النهاية in.php وres.php ومفتاح API واحد. يضع هذا الدليل جدول مطابقة لكل استدعاء، مع أمثلة Python وJavaScript وخطة تبديل تدريجي دون توقّف.

لماذا يستحق الانتقال إلى CaptchaAI؟

تعتمد واجهة EndCaptcha على SOAP/XML وأسماء طرق خاصة، وهو نمط صار مرهقاً في الصيانة. يقدّم CaptchaAI بديلاً أبسط في ثلاث نقاط:

  • مفتاح API واحد بدل زوج اسم المستخدم وكلمة المرور، ما يقلّص مساحة تسريب بيانات الاعتماد.
  • نقطتا نهاية فقطin.php للإرسال وres.php للاستطلاع — عبر HTTP POST/GET القياسي دون غلاف SOAP.
  • تسعير قائم على الـ Threads مع حلول غير محدودة لكل Thread شهرياً، فتصبح التكلفة قابلة للتنبؤ عند الحجم الكبير.

الفرق المعماري بين الواجهتين

قبل لمس الشيفرة، ثبّت الفروق البنيوية الخمسة التالية التي تحدّد حجم التعديل المطلوب:

الجانب EndCaptcha CaptchaAI
البروتوكول SOAP/XML أو HTTP POST HTTP POST/GET (REST)
الإرسال /Captcha/Upload أو WSDL https://ocr.captchaai.com/in.php
النتيجة /Captcha/GetText أو WSDL https://ocr.captchaai.com/res.php
المصادقة اسم المستخدم + كلمة المرور مفتاح الـ API
الاستجابة XML/مخصّص JSON (json=1) أو نص عادي

نصيحة عملية: أبقِ حساب EndCaptcha نشطاً طوال الاختبار المتوازي، ولا تحذف بياناته إلا بعد تطابق النتائج على الإنتاج الفعلي.

مطابقة المعاملات

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

معامل EndCaptcha معامل CaptchaAI ملاحظات
username key يستخدم CaptchaAI مفتاح API واحداً
password غير مطلوب؛ مفتاح الـ API يغطّي المصادقة
captchaData (base64) body (base64) نفس بيانات الصورة بترميز base64
captchaType method معرّفات نوع مختلفة
siteKey googlekey لأنواع reCAPTCHA
pageUrl pageurl نفس المفهوم باختلاف حالة الأحرف
captchaId id معرّف المهمة المستخدم في الاستطلاع

مطابقة أنواع CAPTCHA

يغطّي الجدول الأنواع الأكثر شيوعاً في EndCaptcha وما يقابلها من طرق CaptchaAI:

نوع EndCaptcha طريقة CaptchaAI معاملات CaptchaAI
صورة/OCR method=base64 body={base64_image}
reCAPTCHA v2 method=userrecaptcha googlekey، pageurl
Cloudflare Turnstile method=turnstile sitekey، pageurl

ملاحظة مهمة قبل الترحيل: لا يحلّ CaptchaAI حالياً hCaptcha أو FunCaptcha (Arkose Labs)، وGeeTest v4 ما يزال قيد الإطلاق. إن كان تدفّقك القديم يعتمد على أحدها فلا مقابل مباشر له بعد؛ أمّا reCAPTCHA v2/v3 وTurnstile وGeeTest v3 والصور والشبكات و BLS فكلها مدعومة.

ترحيل الشيفرة

المنطق العام واحد في الحالتين: أرسِل المهمة، احتفظ بالمعرّف، ثم استطلع النتيجة حتى تجهز. ما يتغيّر هو أسماء نقاط النهاية والحقول فقط. قارن نسختَي «قبل» و«بعد».

Python — قبل (EndCaptcha)

import requests

USERNAME = "your_endcaptcha_user"
PASSWORD = "your_endcaptcha_pass"

def solve_image_endcaptcha(image_base64):
    # EndCaptcha image solve
    resp = requests.post("https://api.endcaptcha.com/Captcha/Upload", data={
        "username": USERNAME,
        "password": PASSWORD,
        "captchaData": image_base64,
        "captchaType": "1"
    })
    result = resp.json()
    captcha_id = result.get("captchaId")

    import time
    for _ in range(30):
        time.sleep(5)
        poll = requests.post("https://api.endcaptcha.com/Captcha/GetText", data={
            "username": USERNAME,
            "password": PASSWORD,
            "captchaId": captcha_id
        })
        poll_result = poll.json()
        if poll_result.get("text"):
            return {"solution": poll_result["text"]}
        if poll_result.get("error"):
            return {"error": poll_result["error"]}

    return {"error": "TIMEOUT"}

Python — بعد (CaptchaAI)

import os
import time
import requests

API_KEY = os.environ["CAPTCHAAI_API_KEY"]

def solve_image_captchaai(image_base64):
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_base64,
        "json": 1
    })
    data = resp.json()
    if data.get("status") != 1:
        return {"error": data.get("request")}

    captcha_id = data["request"]

    for _ in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": captcha_id,
            "json": 1
        }).json()
        if result.get("status") == 1:
            return {"solution": result["request"]}
        if result.get("request") != "CAPCHA_NOT_READY":
            return {"error": result.get("request")}

    return {"error": "TIMEOUT"}

Python — reCAPTCHA v2 (CaptchaAI)

def solve_recaptcha_v2(sitekey, pageurl):
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1
    })
    data = resp.json()
    if data.get("status") != 1:
        return {"error": data.get("request")}

    captcha_id = data["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get",
            "id": captcha_id, "json": 1
        }).json()
        if result.get("status") == 1:
            return {"solution": result["request"]}
        if result.get("request") != "CAPCHA_NOT_READY":
            return {"error": result.get("request")}

    return {"error": "TIMEOUT"}

JavaScript — قبل (EndCaptcha)

const axios = require("axios");

const USERNAME = "your_endcaptcha_user";
const PASSWORD = "your_endcaptcha_pass";

async function solveImageEndCaptcha(imageBase64) {
  const submit = await axios.post("https://api.endcaptcha.com/Captcha/Upload", {
    username: USERNAME,
    password: PASSWORD,
    captchaData: imageBase64,
    captchaType: "1",
  });
  const captchaId = submit.data.captchaId;

  for (let i = 0; i < 30; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await axios.post("https://api.endcaptcha.com/Captcha/GetText", {
      username: USERNAME,
      password: PASSWORD,
      captchaId,
    });
    if (poll.data.text) return { solution: poll.data.text };
    if (poll.data.error) return { error: poll.data.error };
  }
  return { error: "TIMEOUT" };
}

JavaScript — بعد (CaptchaAI)

const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;

async function solveImageCaptchaAI(imageBase64) {
  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: { key: API_KEY, method: "base64", body: imageBase64, json: 1 },
  });
  if (submit.data.status !== 1) return { error: submit.data.request };

  const captchaId = submit.data.request;

  for (let i = 0; i < 30; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
    });
    if (poll.data.status === 1) return { solution: poll.data.request };
    if (poll.data.request !== "CAPCHA_NOT_READY") return { error: poll.data.request };
  }
  return { error: "TIMEOUT" };
}

اختلافات جوهرية يجب الانتباه إليها

بعد مطابقة الاستدعاءات، هذه النقاط التي تفاجئ الفرق غالباً أثناء التبديل:

المجال EndCaptcha CaptchaAI
المصادقة زوج اسم مستخدم + كلمة مرور مفتاح API واحد
تنسيق الخطأ JSON مخصّص بحقل error حقل request القياسي مع رموز خطأ
الاستطلاع POST إلى نقطة نهاية منفصلة GET إلى res.php بمعاملات استعلام
التحقق من الرصيد طريقة SOAP منفصلة res.php?action=getbalance&key=KEY
الإبلاغ عن حل خاطئ طريقة منفصلة res.php?action=reportbad&id=ID&key=KEY

قائمة تحقق للترحيل

اتبع هذه الخطوات لتبديل آمن قابل للتراجع في أي لحظة:

الخطوة الحالة
إنشاء حساب CaptchaAI والحصول على مفتاح الـ API
مطابقة جميع استدعاءات EndCaptcha بمكافئاتها في CaptchaAI
استبدال المصادقة (اسم المستخدم/كلمة المرور ← مفتاح الـ API)
تحديث نقطة نهاية الإرسال (/Captcha/Upload/in.php)
تحديث نقطة نهاية الاستطلاع (/Captcha/GetText/res.php)
تحديث تحليل الاستجابة لقراءة status وrequest
تشغيل اختبار متوازٍ مع كلا المزوّدين
تبديل حركة الإنتاج تدريجياً
إزالة بيانات اعتماد EndCaptcha

كل بند مستقل عن غيره، فيمكنك التوقّف أو التراجع عند أي خطوة قبل إزالة بيانات الاعتماد دون كسر المسار القائم.

سيناريو عملي: تبديل تدريجي دون توقّف

تخيّل فريقاً يدير أداة مراقبة أسعار لمتجر إلكتروني خليجي، يعتمد على EndCaptcha لحلّ الصور و reCAPTCHA v2 أثناء جمع البيانات. بدل التبديل دفعةً واحدة، شغّل المزوّدين بالتوازي:

  1. أنشئ حساباً على captchaai.com واحصل على مفتاح الـ API من لوحة التحكم.
  2. ابدأ بخطة صغيرة مثل BASIC ($15 شهرياً، 5 threads) للاختبار المحدود، أو STANDARD ($30 شهرياً، 15 threads) لحجم أعلى.
  3. مرّر نسبة صغيرة — 10% مثلاً — عبر CaptchaAI وقارن معدل الحل وزمن الاستجابة على السجلات نفسها.
  4. عند تطابق النتائج، بدّل باقي الحركة ثم أزل بيانات اعتماد EndCaptcha.

الأسعار بالدولار الأمريكي، وعدد الحلول غير محدود داخل كل Thread، لذا تتحكم في الإنتاجية عبر عدد الـ threads لا عبر فاتورة لكل عملية حل.

نقل إعدادات الوكيل (Proxy)

إذا كنت تمرّر الطلبات عبر خادم وسيط، يقبل CaptchaAI معاملي proxy وproxytype بالصيغة المعتادة لدى معظم المزوّدين، فلا حاجة لإعادة هيكلة منطق الوكيل:

  • proxy=user:pass@host:port
  • proxytype=HTTP أو SOCKS5

استكشاف الأخطاء وإصلاحها

بعد التبديل، تنحصر غالبية الأعطال في أربع حالات؛ يلخّص الجدول سببها وحلّها:

المشكلة السبب الحل
ERROR_KEY_DOES_NOT_EXIST استخدام اسم مستخدم EndCaptcha بدل مفتاح الـ API استخدم مفتاح CaptchaAI من لوحة التحكم
فشل تحليل الاستجابة بنية JSON مختلفة حدّث الكود ليقرأ حقلي status وrequest
المعامل method مفقود كان EndCaptcha يعتمد ترقيم captchaType طابقه مع أسماء طرق CaptchaAI (base64، userrecaptcha…)
مهلة انتهاء على reCAPTCHA مهل افتراضية مختلفة اضبط الاستطلاع على 60 محاولة × 5 ثوانٍ لأنواع الرموز

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

هل أحتاج إلى تعديل منطق حل الكابتشا نفسه عند الترحيل؟

لا. ما يتغيّر هو طبقة الاتصال فقط — أسماء نقاط النهاية والمعاملات وتنسيق الاستجابة. أما تسلسل العمل (إرسال المهمة، الاحتفاظ بالمعرّف، ثم استطلاع النتيجة) فيبقى كما هو، فيكون التعديل محصوراً في دالة الاتصال بالمزوّد.

كم يستغرق الاختبار المتوازي قبل تبديل الإنتاج؟

لا توجد مدة ثابتة؛ المعيار حجم العيّنة لا الزمن. شغّل المزوّدين جنباً إلى جنب حتى يتطابق معدل الحل وزمن الاستجابة عبر عدد كافٍ من الطلبات الحقيقية بأنواع الكابتشا التي تهمّك، ثم بدّل الحركة تدريجياً.

هل يدعم CaptchaAI أنواع الكابتشا نفسها التي كنت أحلّها عبر EndCaptcha؟

يدعم CaptchaAI الصور/OCR والشبكات و reCAPTCHA v2/v3 و Cloudflare Turnstile و Cloudflare Challenge و GeeTest v3 و BLS، مع CaptchaFox و Friendly Captcha و Lemin في مرحلة تجريبية (beta). لكنه لا يحلّ حالياً hCaptcha أو FunCaptcha، وGeeTest v4 قيد الإطلاق، فتحقّق من نوعك قبل التبديل.

كيف أتحقق من رصيدي بعد الترحيل؟

استخدم نقطة النهاية res.php?action=getbalance&key=KEY؛ تُعيد رصيدك مباشرةً، وهي أبسط من استدعاء SOAP المنفصل في EndCaptcha.


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

أدلة ذات صلة

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