الانتقال من 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 أثناء جمع البيانات. بدل التبديل دفعةً واحدة، شغّل المزوّدين بالتوازي:
- أنشئ حساباً على captchaai.com واحصل على مفتاح الـ API من لوحة التحكم.
- ابدأ بخطة صغيرة مثل BASIC ($15 شهرياً، 5 threads) للاختبار المحدود، أو STANDARD ($30 شهرياً، 15 threads) لحجم أعلى.
- مرّر نسبة صغيرة — 10% مثلاً — عبر CaptchaAI وقارن معدل الحل وزمن الاستجابة على السجلات نفسها.
- عند تطابق النتائج، بدّل باقي الحركة ثم أزل بيانات اعتماد EndCaptcha.
الأسعار بالدولار الأمريكي، وعدد الحلول غير محدود داخل كل Thread، لذا تتحكم في الإنتاجية عبر عدد الـ threads لا عبر فاتورة لكل عملية حل.
نقل إعدادات الوكيل (Proxy)
إذا كنت تمرّر الطلبات عبر خادم وسيط، يقبل CaptchaAI معاملي proxy وproxytype بالصيغة المعتادة لدى معظم المزوّدين، فلا حاجة لإعادة هيكلة منطق الوكيل:
proxy=user:pass@host:portproxytype=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.
الخطوات التالية
- ابدأ بحلّ أول كابتشا خلال خمس دقائق
- حلّ reCAPTCHA v2 عبر الـ API خطوة بخطوة
- حلّ Cloudflare Turnstile عبر الـ API
- حلّ GeeTest v3 عبر الـ API