حين تعود خلايا صورة الشبكة خاطئة — نقرات في المربعات غير الصحيحة أو رسالة ERROR_CAPTCHA_UNSOLVABLE — يكون السبب في أغلب الحالات في طريقة إرسال الصورة إلى CaptchaAI، لا في محرّك الحل ذاته. فمعلمة حجم الشبكة، وطريقة التقاط الصورة، ونص التعليمات، وأسلوب ترقيم الخلايا هي العوامل التي تحدّد ما إذا كانت الإحداثيات ستطابق التحدي أم لا.
ابدأ التشخيص من العَرَض الظاهر: هل انزاحت كل النقرات بمقدار مربع واحد؟ أم أن كل الخلايا خاطئة تماماً؟ أم أن الحل غير قابل للاستخدام من الأساس؟ كل عَرَض من هذه الأعراض يشير إلى طبقة مختلفة من المشكلة، وتحديد الطبقة الصحيحة يختصر عليك دقائق من التجربة العشوائية.
كيف يرقّم CaptchaAI خلايا صور الشبكة
يستقبل CaptchaAI صورة الشبكة، ويحلّل كل خلية على حدة، ثم يعيد مصفوفة من المؤشرات المطابقة للتعليمات. تُرقَّم الخلايا من اليسار إلى اليمين ومن الأعلى إلى الأسفل — وحتى في الصفحات التي تُعرض بالعربية من اليمين إلى اليسار، يبقى ترقيم الشبكة كما تُصدره reCAPTCHA دون انعكاس:
3×3 Grid: 4×4 Grid:
1 2 3 1 2 3 4
4 5 6 5 6 7 8
7 8 9 9 10 11 12
13 14 15 16
تأتي الاستجابة على هذا الشكل: [1, 3, 6, 9] — أي أن الخلايا 1 و3 و6 و9 تحتوي على الكائنات المطلوبة. أي خلل في فهم هذا الترقيم — في الحجم أو في نقطة البداية — يُترجَم مباشرةً إلى نقرات في مواضع خاطئة.
الفرز السريع لأخطاء صور الشبكة
قبل الغوص في الكود، حدِّد العَرَض في الجدول التالي لتصل مباشرةً إلى الطبقة المسؤولة عن الخطأ:
| العَرَض الظاهر | السبب الأرجح أولاً | ما تفحصه فوراً |
|---|---|---|
| كل النقرات في أماكن خاطئة | حجم شبكة غير مطابق أو صورة غير أصلية | grid_size وطريقة التقاط الصورة |
| انزياح ثابت بمقدار خلية واحدة | فهرسة تبدأ من 1 مقابل فهرسة تبدأ من 0 | منطق التحويل قبل النقر |
الحل يعيد ERROR_CAPTCHA_UNSOLVABLE |
تعليمات غير دقيقة أو صورة رديئة الجودة | نص التعليمات وجودة الصورة الفعلية |
| نجاح متقطّع وفشل متقطّع | تحدٍّ مختلف أو جلسة غير مستقرة | ثبات الجلسة والتقاط صورة لكل تحدٍّ |
حجم الشبكة غير مطابق للتحدي
أكثر أخطاء الإحداثيات شيوعاً على الإطلاق. إذا كان التحدي شبكة 4×4 وأرسلت grid_size=3x3، فسيختلّ ترقيم الخلايا بالكامل وتُحدَّد المربعات الخاطئة. طابِق دائماً قيمة grid_size مع الشبكة الفعلية المعروضة:
# WRONG — 4×4 grid sent as 3×3
data = {
"key": "YOUR_API_KEY",
"method": "post",
"grid_size": "3x3", # Wrong!
"img_type": "recaptcha",
"instructions": "traffic lights",
"json": 1
}
# CORRECT — match the actual grid
data = {
"key": "YOUR_API_KEY",
"method": "post",
"grid_size": "4x4", # Correct
"img_type": "recaptcha",
"instructions": "traffic lights",
"json": 1
}
اكتشاف حجم الشبكة برمجياً بدل تثبيت قيمة واحدة:
from PIL import Image
img = Image.open("grid_captcha.png")
width, height = img.size
# reCAPTCHA grids are square. 3×3 tiles are ~100px each, 4×4 tiles are ~75px each
tile_width = width // 3
if width % 4 == 0 and (width // 4) < 100:
grid_size = "4x4"
else:
grid_size = "3x3"
print(f"Detected grid size: {grid_size}")
صورة مقتصّة أو مُعاد تحجيمها
إرسال صورة مقتصّة أو مُعاد تحجيمها أو ملتقطة ضمن لقطة شاشة كاملة يغيّر محاذاة الشبكة، فيصبح كل تطابق للإحداثيات خاطئاً. يحتاج CaptchaAI إلى صورة التحدي الأصلية تماماً كما عُرِضت.
الإصلاح: التقط الصورة مباشرةً من إطار reCAPTCHA iframe، لا من لقطة شاشة لكامل الصفحة:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com")
# Switch to reCAPTCHA iframe
iframe = driver.find_element(By.CSS_SELECTOR, 'iframe[title*="recaptcha"]')
driver.switch_to.frame(iframe)
# Get the grid image element
grid_img = driver.find_element(By.CSS_SELECTOR, "img.rc-image-tile-wrapper img")
grid_img.screenshot("grid_captcha.png") # Captures just the grid, not the whole page
تعليمات عامة أو غير مطابقة
يجب أن يطابق نص التعليمات ما يطلبه التحدي بالضبط. التعليمات العامة تقود إلى اختيارات خاطئة للخلايا:
# WRONG — too vague
data["instructions"] = "select images"
# CORRECT — specific instruction from the CAPTCHA
data["instructions"] = "crosswalks"
أرسل نص التعليمات بالإنجليزية كما يظهر في التحدي تماماً، لأن محرّك الحل يطابقه نصّياً ولا يترجمه. وأكثر القيم شيوعاً في تحديات reCAPTCHA:
crosswalksوtraffic lightsوfire hydrantscarsوbusesوmotorcyclesوbicyclesstairsوbridgesوparking meters
إزاحة فهرس الخلية بين 0 و1
يعيد CaptchaAI مؤشرات الخلايا بترقيم يبدأ من 1 (1-based). إذا كان كود الأتمتة لديك يعتمد الترقيم من 0 (0-based)، فاطرح 1 من كل مؤشر قبل النقر. هذا تحديداً هو السبب الكلاسيكي وراء انزياح كل النقرات بمربع واحد:
import json
# CaptchaAI returns 1-based indices
solution = json.loads(result["request"]) # e.g., [1, 3, 6, 9]
# Convert to 0-based for Selenium click automation
zero_based = [cell - 1 for cell in solution]
# Click grid cells using 0-based index
tiles = driver.find_elements(By.CSS_SELECTOR, ".rc-image-tile-wrapper img")
for idx in zero_based:
tiles[idx].click()
تنسيق صورة غير مدعوم
يدعم CaptchaAI صيغ JPG وJPEG وPNG وGIF. الصيغ الأخرى تعيد ERROR_WRONG_FILE_EXTENSION. حوّل الصورة إلى PNG قبل الإرسال إن لزم، مع الحفاظ على أبعادها الأصلية:
# WRONG — WebP or BMP
files = {"file": open("grid.webp", "rb")} # Not supported
# CORRECT — convert to PNG first
from PIL import Image
img = Image.open("grid.webp")
img.save("grid.png", "PNG")
files = {"file": open("grid.png", "rb")}
شجرة القرار للتشخيص
اتبع هذا المسار من الأعلى إلى الأسفل؛ أول إجابة بـ«لا» هي غالباً مصدر الخطأ:
Grid cells are wrong
↓
Is grid_size correct (3x3 or 4x4)? → No → Fix grid_size parameter
↓ Yes
Is the image the original CAPTCHA (not cropped)? → No → Capture directly from iframe
↓ Yes
Is instruction text specific? → No → Use exact CAPTCHA instruction text
↓ Yes
Using 1-based indexing for clicks? → No → Convert solution to 0-based
↓ Yes
Image in supported format (JPG/PNG)? → No → Convert image format
↓ Yes
Report tiles to CaptchaAI via reportbad
الإبلاغ عن حل غير صحيح
إذا بقيت الإحداثيات خاطئة باستمرار رغم صحة كل المعلمات، فأبلغ عن الحل حتى لا تدفع مقابل نتيجة غير صالحة:
requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "reportbad",
"id": task_id,
"json": 1
})
لإرسال البلاغ فائدتان مباشرتان:
- يساعد CaptchaAI على تحسين دقة الحل لهذا النوع من التحديات.
- قد يُعيد إليك تكلفة الحل الخاطئ عند تأكّد عدم صحته.
سيناريو عملي: أتمتة اختبار بوابة حجوزات إقليمية
تخيّل مهندس اختبار جودة في فريق أتمتة بالرياض يتحقق من مسار تسجيل في بوابة حجوزات تعرض تحدي صور شبكية من reCAPTCHA v2. تعمل النقرات في بيئة التطوير، لكنها تفشل في الإنتاج مع انزياح ثابت بمربع واحد. المسار المنطقي للتشخيص هو ذاته ترتيب شجرة القرار أعلاه:
- يتأكد أولاً أن
grid_sizeيُقرأ ديناميكياً لكل تحدٍّ، لا يُثبَّت على3x3، لأن بعض التحديات تتحوّل إلى شبكة 4×4 عند ارتفاع مستوى الاشتباه. - ثم يتحقق أن الصورة تُلتقط من إطار الـ iframe لا من لقطة شاشة كاملة، فمحاذاة الشبكة حساسة لأي اقتصاص.
- وأخيراً يكتشف أن الكود يمرّر مؤشرات تبدأ من 1 مباشرةً إلى مصفوفة عناصر تبدأ من 0 في Selenium — وهذا بالضبط مصدر الإزاحة.
تصحيح خطوة الطرح وحدها يعيد المسار إلى الاستقرار. هذا الترتيب — من المعلمة، إلى الالتقاط، إلى الفهرسة — يوفّر ساعات مقارنةً بتعديل الكود عشوائياً.
الأسئلة الشائعة
هل يؤثر تحويل الصورة إلى WebP على دقة الحل؟
لا يقبل CaptchaAI صيغة WebP أصلاً، وسيعيد ERROR_WRONG_FILE_EXTENSION قبل أي محاولة حل. حوّل الصورة إلى PNG أو JPG مع الحفاظ على أبعادها الأصلية دون إعادة تحجيم، لأن التحجيم نفسه قد يُفسد محاذاة الشبكة ويولّد إحداثيات خاطئة.
كيف أعرف أن الشبكة 3×3 أم 4×4 دون تخمين؟
افحص أبعاد الصورة برمجياً: خلايا 3×3 تقارب 100 بكسل لكل مربع، وخلايا 4×4 تقارب 75 بكسل. المقطع البرمجي في قسم «حجم الشبكة» أعلاه يؤتمت هذا الاكتشاف بدل تثبيت قيمة واحدة قد لا تطابق التحدي.
لماذا ينجح بعض التحديات ويفشل بعضها الآخر رغم نفس الكود؟
غالباً لأن الجلسة غير مستقرة أو لأن الصورة تُلتقط بعد أن يكون التحدي قد تغيّر. تأكد من التقاط صورة جديدة لكل تحدٍّ على حدة، ومن أن قيمة grid_size تُقرأ لحظة الالتقاط لا مرة واحدة في بداية التشغيل.
هل يمكنني استرداد تكلفة الحل الخاطئ؟
نعم، عبر إرسال reportbad مع معرّف المهمة كما في القسم أعلاه. الإبلاغ المنتظم عن الحلول غير الصحيحة يساعد على تحسين الدقة، وقد يُرجِع إليك تكلفة الحل غير الصالح.
صحّح حجم الشبكة ونص التعليمات وأسلوب الفهرسة قبل الإرسال، فمعظم أخطاء هذا النوع تأتي من الإرسال نفسه لا من عملية الحل وحدها. بعد ضبط هذه العناصر، ابدأ بحلّ صور الشبكة بدقة عبر CaptchaAI.