يعتمد CaptchaAI على استجابات نصية بسيطة وسريعة القراءة. هذا مفيد جدًا عندما تبني عميلًا خفيفًا أو تريد اختبار الطلبات عبر curl أو من سكربت صغير، لكنه يتطلب منك فهمًا واضحًا لكيفية التمييز بين النجاح والانتظار والخطأ. هذا الدليل يشرح تلك التنسيقات وكيف تتعامل معها برمجيًا بدون التباس.
استجابة نقطة الإرسال in.php
استجابة النجاح
OK|TASK_ID
مثال: OK|73548291
استجابة الخطأ
ERROR_CODE
مثال: ERROR_WRONG_USER_KEY
تحليل الاستجابة
resp = requests.get("https://ocr.captchaai.com/in.php", params={...})
if resp.text.startswith("OK|"):
task_id = resp.text.split("|")[1]
else:
error = resp.text
raise Exception(f"Submit failed: {error}")
const resp = await axios.get("https://ocr.captchaai.com/in.php", { params });
if (resp.data.startsWith("OK|")) {
const taskId = resp.data.split("|")[1];
} else {
throw new Error(`Submit failed: ${resp.data}`);
}
استجابة نقطة الاستطلاع res.php
استجابة غير جاهزة
CAPCHA_NOT_READY
المهمة لا تزال قيد المعالجة. انتظر 5 ثوان وقم بالاستطلاع مرة أخرى.
النجاح - اختبارات CAPTCHA القائمة على الرمز المميز
بالنسبة إلى reCAPTCHA وTurnstile وhCaptcha وما شابه ذلك:
OK|03AGdBq24PBCbw...long_token_string
النجاح — Image/OCR CAPTCHAs
OK|abc123
النص بعد OK| هو النص الذي تم التعرف عليه من الصورة.
النجاح — GeeTest
OK|challenge:abc123,validate:def456,seccode:ghi789
هنا تحتاج إلى تحليل كل حقل بشكل منفصل:
if result.text.startswith("OK|"):
data = result.text.split("|")[1]
parts = dict(item.split(":") for item in data.split(","))
challenge = parts["challenge"]
validate = parts["validate"]
seccode = parts["seccode"]
النجاح — Cloudflare Challenge
إرجاع قيمة ملف تعريف الارتباط cf_clearance ووكيل المستخدم:
OK|cf_clearance=abc123;user_agent=Mozilla/5.0...
استجابة الخطأ
ERROR_CODE
قالب موحد لتحليل النتيجة
def parse_result(response_text):
if response_text == "CAPCHA_NOT_READY":
return {"status": "pending"}
if response_text.startswith("OK|"):
return {"status": "solved", "result": response_text.split("|", 1)[1]}
return {"status": "error", "error": response_text}
استجابة طلب الرصيد
GET https://ocr.captchaai.com/res.php?key=API_KEY&action=getbalance
الرد:
1.234
رقم عشري يمثل رصيدك بالدولار الأمريكي.
balance = float(requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "getbalance"
}).text)
print(f"Balance: ${balance:.2f}")
نقاط الإبلاغ عن النتائج
تقرير جيد (الحل الصحيح)
GET https://ocr.captchaai.com/res.php?key=API_KEY&action=reportgood&id=TASK_ID
الرد: OK_REPORT_RECORDED
الإبلاغ عن خطأ (حل غير صحيح)
GET https://ocr.captchaai.com/res.php?key=API_KEY&action=reportbad&id=TASK_ID
الرد: OK_REPORT_RECORDED
يساعد الإبلاغ عن النتائج غير الصحيحة على تحسين الجودة التشغيلية، وقد يدخل في آلية التعويض حسب حالة المهمة ونوع التحدي.
رموز الأخطاء الشائعة
| رمز الخطأ | المعنى | الإجراء |
|---|---|---|
ERROR_WRONG_USER_KEY |
مفتاح API غير صالح | تحقق من مفتاحك |
ERROR_KEY_DOES_NOT_EXIST |
المفتاح غير مسجل | تحقق من لوحة التحكم |
ERROR_ZERO_BALANCE |
الرصيد غير كافٍ | أضف رصيدًا إلى الحساب |
ERROR_NO_SLOT_AVAILABLE |
لا توجد سعة متاحة حاليًا | أعد المحاولة بعد 5 ثوانٍ |
ERROR_CAPTCHA_UNSOLVABLE |
التحدي تعذر حله | أرسل مهمة جديدة إذا كان ذلك مناسبًا |
ERROR_BAD_DUPLICATES |
تم رفض المهمة المكررة | انتظر قليلًا قبل إعادة الإرسال |
ERROR_WRONG_CAPTCHA_ID |
معرف المهمة غير صالح | تحقق من قيمة معرف المهمة |
ERROR_EMPTY_ACTION |
معلمة action مفقودة |
أضف action=get |
IP_BANNED |
كثرة الطلبات الخاطئة من عنوان IP | أوقف الطلبات مؤقتًا، راجع الإعدادات، ثم أعد المحاولة لاحقًا |
مثال كامل للاستطلاع الدوري
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_captcha(submit_params, timeout=300):
"""Generic solver with proper response handling."""
submit_params["key"] = API_KEY
# Submit
resp = requests.get("https://ocr.captchaai.com/in.php", params=submit_params)
if not resp.text.startswith("OK|"):
raise Exception(f"Submit error: {resp.text}")
task_id = resp.text.split("|")[1]
# Poll
deadline = time.time() + timeout
while time.time() < deadline:
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id
})
parsed = parse_result(result.text)
if parsed["status"] == "pending":
continue
elif parsed["status"] == "solved":
return parsed["result"]
else:
raise Exception(f"Solve error: {parsed['error']}")
raise TimeoutError(f"Task {task_id} timed out after {timeout}s")
الأسئلة الشائعة
لماذا تستخدم الاستجابة الفاصل | بدل JSON؟
لأن CaptchaAI يركز على البساطة وسهولة الدمج. الصيغة النصية أصغر حجمًا وأسهل في الفحص اليدوي من JSON، خصوصًا في أدوات مثل curl أو السكربتات السريعة. وعندما تكون النتيجة أكثر تركيبًا، كما في GeeTest، تأتي البيانات المنظمة بعد OK| ضمن تنسيق يمكن تحليله بسهولة.
كيف أتعامل مع أخطاء الشبكة؟
لف مكالمات واجهة البرمجة داخل try/except ثم أعد المحاولة عند ConnectionError أو Timeout. أخطاء الشبكة تختلف عن أخطاء الخدمة نفسها، لذلك من الأفضل الاحتفاظ بمسار واضح يميز بين فشل الاتصال، ونتيجة CAPCHA_NOT_READY، وأكواد الخطأ القادمة من الواجهة.
ما هو الحد الأقصى لطول الرمز؟
يمكن أن تصل رموز reCAPTCHA إلى 500 حرف تقريبًا. استخدم دائمًا split("|", 1) (أقصى تقسيم 1) لتجنب تقسيم الرمز المميز نفسه.
النقاشات (0)
شارك في النقاش
سجّل الدخول لمشاركة رأيك.
تسجيل الدخوللا توجد تعليقات بعد.