نادراً ما يكون فشل حل كابتشا الصور عشوائياً. فمعظم الأخطاء تعود إلى ثلاثة مصادر محدَّدة يمكنك السيطرة عليها بالكامل: طريقة ترميز الصورة قبل إرسالها، وجودة الصورة نفسها، والمعلمات التي تخبر الحل بما يتوقعه من النص. اضبط هذه العناصر الثلاثة وستختفي أغلب حالات «النص الخاطئ» دون أي تغيير في الخدمة.
هذا الدليل مرتّب حسب اللحظة التي يظهر فيها الخطأ: أولاً أخطاء رفع الصورة، ثم أخطاء النص المُعاد، ثم مشكلات الجودة التي تُفسد التعرف قبل أن يبدأ أصلاً. لكل حالة سبب واضح وإصلاح جاهز للنسخ عبر CaptchaAI API.
مثال عملي من السوق المحلي
تخيّل فريق تطوير في القاهرة يؤتمت اختبار الجودة (QA) لنموذج التسجيل الخاص بمنصته، حيث يعرض النموذج كابتشا صورة مكوّنة من ستة أرقام. في البداية كان الحل يعيد إجابات صحيحة بنسبة متذبذبة لأن الصور كانت تُلتقط بحجم صغير وتُرسَل أحياناً بادئة data:image كاملة. بعد تثبيت الترميز الصحيح وإضافة numeric=1 وmin_len=6 وmax_len=6، استقر معدل القراءة الصحيحة. الدرس هنا أنّ الإصلاح الحقيقي جاء من ضبط المُدخلات، لا من انتظار «حل أذكى».
أخطاء رفع الصورة إلى الخدمة
هذه الأخطاء تحدث قبل أن يرى الحل أي محتوى، وسببها غالباً في كودك أنت لا في الصورة.
ERROR_WRONG_FILE_EXTENSION
- السبب: الصورة ليست بتنسيق مدعوم، أو أنّ سلسلة base64 غير صالحة. الخطأ الأكثر شيوعاً هو إرسال بادئة data URI بالكامل بدل الترميز الخام.
- الإصلاح: أرسل الترميز الخام دون بادئة data URI:
import base64
# Ensure proper encoding
with open("captcha.png", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
# Don't include the data URI prefix
# WRONG: "data:image/png;base64,iVBOR..."
# RIGHT: "iVBOR..."
ERROR_ZERO_CAPTCHA_FILESIZE
- السبب: ملف الصورة فارغ أو فشل التنزيل، وهو ما يحدث كثيراً عندما تُرسل الصورة قبل اكتمال تحميلها في الصفحة.
- الإصلاح: تحقّق من الحجم قبل الإرسال، وأعِد الالتقاط إن كان صفراً:
import os
# Check file size before submitting
if os.path.getsize("captcha.png") == 0:
print("Image file is empty — re-download")
# Re-capture the captcha
ERROR_TOO_BIG_CAPTCHA_FILESIZE
- السبب: تجاوزت الصورة الحد الأقصى للحجم (عادةً 600 كيلوبايت). هذا شائع مع لقطات الشاشة الكاملة بدل اقتصاص منطقة الكابتشا وحدها.
- الإصلاح: أعِد الحفظ بضغطٍ يحافظ على وضوح النص:
from PIL import Image
import io
img = Image.open("captcha.png")
# Reduce quality without losing text clarity
buffer = io.BytesIO()
img.save(buffer, format="PNG", optimize=True)
عندما يعيد الحل نصاً غير صحيح
هنا نجح الإرسال لكن النتيجة خاطئة. الحل لا يقرأ نيّتك، لذا كل معلومة تعرفها مسبقاً عن شكل الكابتشا يجب أن تمرّرها كمعلمة تلميح لتضييق الاحتمالات.
أحرف تُقرأ خطأً بشكل متكرر
- السبب: يخلط الحل بين الأحرف المتشابهة بصرياً مثل 0/O و1/l/I و5/S.
- الإصلاح: استخدم معلمات التلميح لتقييد مجموعة الأحرف؛ فإذا كان الكابتشا أرقاماً فقط أو حروفاً فقط، أخبر الحل بذلك صراحةً:
# If captcha is digits only
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "base64", "body": b64,
"numeric": 1, # 1 = digits only
"json": 1
})
# If captcha is letters only
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "base64", "body": b64,
"numeric": 2, # 2 = letters only
"json": 1
})
حالة الأحرف خاطئة (كبيرة مقابل صغيرة)
- السبب: يفترض الحل الأحرف الصغيرة افتراضياً، فيفشل على المواقع الحسّاسة لحالة الأحرف.
- الإصلاح: فعّل حساسية الحالة عبر
regsense=1:
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "base64", "body": b64,
"regsense": 1, # Case-sensitive
"json": 1
})
أحرف زائدة أو ناقصة
- السبب: تُفسَّر الضوضاء في الخلفية كأحرف إضافية، أو تندمج أحرف متلاصقة فتُقرأ كحرف واحد.
- الإصلاح: ثبّت طول الإجابة بحدّين أدنى وأعلى عندما يكون الطول معروفاً:
# If you know the CAPTCHA is always 6 characters
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "base64", "body": b64,
"min_len": 6,
"max_len": 6,
"json": 1
})
لم يُحسب التعبير الرياضي
- السبب: يقرأ الحل النص "3+7" حرفياً بدل حساب الناتج "10"، وهو نمط شائع في نماذج التسجيل العربية التي تعرض عمليات جمع بسيطة.
- الإصلاح: فعّل الحساب عبر
calc=1:
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "base64", "body": b64,
"calc": 1, # Compute the math expression
"json": 1
})
مشكلات جودة الصورة التي تُفسد التعرف
في هذه الحالات لا تنفع المعلمات، لأن المشكلة في الصورة قبل وصولها للحل. أصلِح المصدر أولاً.
الكابتشا صغير جداً
- المشكلة: الصور الأصغر من 50 بكسل ارتفاعاً تفقد تفاصيل الأحرف، فيصبح التعرف تخميناً.
- الإصلاح: التقط الصورة بأكبر حجم متاح. وإذا كانت الصفحة تعرض الكابتشا مصغّراً، ابحث عن رابط مصدر بدقة أعلى:
# Check for higher-res version
img_src = captcha_el.get_attribute("src")
# Some sites use ?size=small — try removing or changing the parameter
high_res_src = img_src.replace("size=small", "size=large")
الكابتشا متحرك
- المشكلة: تستخدم بعض الاختبارات صور GIF متحركة يظهر فيها النص في إطارات معيّنة فقط، فيلتقط سكربتك إطاراً فارغاً.
- الإصلاح: استخرج الإطارات وابحث عن الإطار الذي يحوي النص:
from PIL import Image
gif = Image.open("captcha.gif")
# Extract each frame and find the one with text
for i in range(gif.n_frames):
gif.seek(i)
gif.save(f"frame_{i}.png")
الكابتشا بخلفية شفافة
- المشكلة: ملفات PNG ذات الخلفية الشفافة قد لا تُعرض بشكل صحيح للتعرف الضوئي، فتظهر الأحرف على خلفية سوداء أو مشوّهة.
- الإصلاح: أضِف خلفية بيضاء قبل الإرسال:
from PIL import Image
img = Image.open("captcha.png").convert("RGBA")
background = Image.new("RGBA", img.size, (255, 255, 255, 255))
background.paste(img, mask=img)
background.convert("RGB").save("captcha_white_bg.png")
أبلغ عن الحلول الخاطئة لتحسين الدقة
عندما يعيد CaptchaAI نصاً خاطئاً رغم صحة إعدادك، لا تتجاهل النتيجة — أبلِغ عنها. الإبلاغ يغذّي منظومة التصحيح وقد يعيد تكلفة الحل إلى رصيدك. أبلِغ في الحالات التالية:
- عندما يرفض الموقع الإجابة رغم أنها تبدو صحيحة.
- عندما يتكرر الخطأ نفسه على نوع الكابتشا ذاته.
- عندما تتأكد من صحة الترميز والمعلمات لكن النص يعود خاطئاً.
# Report bad answer
requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "reportbad",
"id": task_id
})
اجعل هذا الاستدعاء جزءاً من منطق التحقق لديك: إن رفض الموقع الإجابة، أرسل reportbad تلقائياً ثم أعِد المحاولة بلقطة جديدة.
جدول معلمات ضبط الدقة
اعتمد هذا الجدول كمرجع سريع لاختيار المعلمة المناسبة حسب شكل الكابتشا:
| المعلمة | متى تستخدمها | الأثر |
|---|---|---|
numeric=1 |
أرقام فقط | يزيل الخلط بين الحرف والرقم |
numeric=2 |
حروف فقط | يزيل الخلط بين الحرف والرقم |
min_len / max_len |
طول معروف | يمنع الأحرف الزائدة أو الناقصة |
regsense=1 |
حالة الأحرف مهمة | يحافظ على الأحرف الكبيرة والصغيرة |
calc=1 |
تعبير رياضي | يعيد الناتج المحسوب |
phrase=1 |
يحتوي مسافات | يسمح بإجابات متعددة الكلمات |
language=1 |
نص سيريلي | يستخدم مجموعة الأحرف الصحيحة |
language=2 |
نص لاتيني | يستخدم مجموعة الأحرف الصحيحة |
القاعدة العملية: ابدأ بأقل عدد من المعلمات، ثم أضِف واحدة في كل مرة وراقب أثرها. تكديس كل المعلمات دفعة واحدة يجعل تشخيص أي منها ساعدت أو أضرّت أمراً صعباً.
الأسئلة الشائعة
لماذا يعيد الحل نصاً يبدو صحيحاً لكنّ الموقع يرفضه؟
الأرجح أنّ رمز الكابتشا انتهت صلاحيته قبل إرسال الإجابة، أو أنّ الموقع حسّاس لحالة الأحرف بينما أرسلت أحرفاً صغيرة. قلّل الزمن بين الالتقاط والإرسال، وفعّل regsense=1 إن كانت الحالة مهمة.
كيف أتعامل مع كابتشا بأرقام هندية أو نص غير لاتيني؟
لا تفترض أنّ numeric=1 يناسب كل الأرقام، فهو موجّه للأرقام اللاتينية. مع النصوص غير اللاتينية احذف معلمة language ودع الحل يكتشف مجموعة الأحرف تلقائياً، والتقط الصورة بأعلى دقة ممكنة لتقليل التخمين.
متى أتجنّب استخدام regsense؟
عندما يقبل الموقع الإجابة بأي حالة. تفعيل حساسية الحالة دون حاجة يضيف احتمالات خطأ إضافية بين الحروف المتشابهة، فيرتفع معدل القراءة الخاطئة بلا فائدة.
هل يعيد الإبلاغ عن حل خاطئ تكلفته دائماً؟
الإبلاغ عبر reportbad يحسّن الدقة على المدى الأطول وقد يعيد تكلفة الحل، لكنه ليس ضماناً باسترداد كل طلب. اعتبره أداة جودة، لا آلية استرداد مالي.
هل أحل الكابتشا الصوتي بالطريقة نفسها؟
لا. الكابتشا الصوتي يتطلب مساراً مختلفاً عن التعرف الضوئي على الصور. راجع وثائق CaptchaAI لمعرفة الدعم المتاح لهذا النوع.