دروس API

كيفية حل BLS CAPTCHA باستخدام Node.js وCaptchaAI

حل BLS CAPTCHA من Node.js يختصر في أربع خطوات ثابتة: التقط رمز التعليمات وصور الشبكة التسع، حوّلها إلى base64 وأرسلها إلى CaptchaAI، استطلع النتيجة حتى تعود مصفوفة بأرقام الخلايا، ثم انقر تلك الخلايا داخل الصفحة. الاستدعاء نفسه سطران في axios؛ ما يفصل بين سكربت ينجح مرة واحدة وسكربت يعمل يومياً بلا تدخل هو طريقة التقاط الصور، وضبط المهلات، وربط أرقام الخلايا المعادة بعناصر DOM الصحيحة.

هذا الدليل مكتوب لمن يبني أداة أتمتة أو اختبار جودة على نموذج يملكه أو يديره بتفويض، ويريد مساراً واضحاً من الصفحة إلى الرمز المحلول دون تخمين.


المتطلبات الأساسية

العنصر القيمة
مفتاح CaptchaAI API من لوحة التحكم على captchaai.com
Node.js 14+
المكتبات axios مع puppeteernpm install axios puppeteer
نوع CAPTCHA BLS — مدعوم عبر method=bls

احتفظ بمفتاح الـ API في متغيّر بيئة لا داخل الملف، خصوصاً إذا كان السكربت سيُنشر لاحقاً على خادم أو داخل Docker. أي تسريب للمفتاح يعني استهلاك رصيدك من جهة أخرى.


بنية شبكة BLS ورمز التعليمات

BLS CAPTCHA يعرض تسع صور في شبكة 3×3، مرقّمة من اليسار إلى اليمين ومن الأعلى إلى الأسفل:

1 | 2 | 3
---------
4 | 5 | 6
---------
7 | 8 | 9

فوق الشبكة يظهر رمز تعليمات رقمي — مثل 664 — يحدد ما الذي يجب تحديده. مهمتك ليست تحليل الصور، بل تسليم المدخلات كاملة: الصور التسع مرمّزة base64 مع رمز التعليمات. تعيد CaptchaAI مصفوفة بأرقام الخلايا المطابقة، مثل [1, 4, 7, 8]، وأنت من ينقرها في المتصفح.

نقطتان تختصران معظم الأخطاء لاحقاً: أرسل الصور التسع دائماً بالترتيب نفسه الظاهر في الصفحة، واستخدم بادئة data URI صحيحة — إما data:image/png;base64, أو data:image/gif;base64,.


الخطوة 1: التقاط الصور التسع ورمز التعليمات

افتح الصفحة بـ Puppeteer، اقرأ نص رمز التعليمات، ثم اجمع روابط صور الخلايا. بعض النماذج تضع الصور أصلاً كـ data URI داخل السمة src، وبعضها يضع رابطاً عادياً — الكود التالي يتعامل مع الحالتين ويحوّل الروابط العادية إلى base64 عبر axios:

const axios = require('axios');
const puppeteer = require('puppeteer');

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/bls-form');

// Get instruction code
const instruction = await page.$eval('.bls-instruction', (el) => el.textContent.trim());

// Get all 9 cell image URLs and convert to base64
const cellImages = await page.$$eval('.bls-grid img', (imgs) =>
  imgs.map((img) => img.src)
);

const images = [];
for (const src of cellImages) {
  if (src.startsWith('data:')) {
    images.push(src);
  } else {
    const { data } = await axios.get(src, { responseType: 'arraybuffer' });
    const b64 = Buffer.from(data).toString('base64');
    images.push(`data:image/png;base64,${b64}`);
  }
}

تحقق من أن images.length === 9 قبل المتابعة؛ الشبكة الناقصة سببها غالباً التقاط مبكر قبل اكتمال التحميل.


الخطوة 2: إرسال الطلب إلى in.php

تُرسل المهمة بطلب POST إلى نقطة النهاية in.php مع method: 'bls' ورمز التعليمات وتسعة حقول باسم image_base64_1 حتى image_base64_9. المعامل json: '1' يجعل الاستجابة كائن JSON سهل القراءة بدل النص الخام، والقيمة المعادة عند النجاح هي معرّف المهمة:

const API_KEY = 'YOUR_API_KEY';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

const params = new URLSearchParams({
  key: API_KEY,
  method: 'bls',
  instructions: instruction,
  json: '1',
});

// Add all 9 images
images.forEach((img, i) => {
  params.append(`image_base64_${i + 1}`, img);
});

const { data: submitData } = await axios.post(
  'https://ocr.captchaai.com/in.php',
  params.toString()
);

if (submitData.status !== 1) throw new Error(submitData.request);
const taskId = submitData.request;
console.log(`Task submitted: ${taskId}`);

سجّل taskId في السجلات مع الطابع الزمني؛ سيوفّر عليك وقتاً طويلاً عند تتبّع طلب فاشل بعد أسبوع.


الخطوة 3: استطلاع النتيجة من res.php

انتظر خمس ثوانٍ ثم ابدأ الاستطلاع الدوري لنقطة النهاية res.php. طالما عاد CAPCHA_NOT_READY فالمهمة قيد المعالجة وعليك المحاولة مجدداً؛ أي رمز آخر هو خطأ فعلي يجب رفعه فوراً بدل الاستمرار في الحلقة:

await sleep(5000);

let selectedCells;
for (let i = 0; i < 30; i++) {
  const { data: pollData } = await axios.get('https://ocr.captchaai.com/res.php', {
    params: { key: API_KEY, action: 'get', id: taskId, json: 1 },
  });

  if (pollData.status === 1) {
    selectedCells = JSON.parse(pollData.request);
    console.log('Selected cells:', selectedCells);
    break;
  }
  if (pollData.request !== 'CAPCHA_NOT_READY') {
    throw new Error(pollData.request);
  }
  await sleep(5000);
}

انتبه إلى أن pollData.request يعود كنص، لذلك يمر عبر JSON.parse ليصبح مصفوفة أرقام قابلة للاستخدام.


الخطوة 4: نقر الخلايا المعادة وإرسال النموذج

المصفوفة المعادة تبدأ من 1، بينما فهرسة عناصر DOM تبدأ من 0 — لذلك cellNum - 1 في السطر التالي ليست تفصيلاً تجميلياً، بل السبب الأكثر شيوعاً لنقر الخلية الخاطئة:

// Click each identified cell
const gridCells = await page.$$('.bls-grid img');
for (const cellNum of selectedCells) {
  await gridCells[cellNum - 1].click();
}

// Submit the form
await page.click('.bls-submit');
console.log(`Solved: clicked cells ${JSON.stringify(selectedCells)}`);
await browser.close();

الناتج المتوقع:

Selected cells: [1, 4, 7, 8]
Solved: clicked cells [1,4,7,8]

سيناريو تشغيلي: مراقبة نماذج BLS من فريق في القاهرة أو الرياض

تخيّل فريقاً صغيراً يشغّل أداة مراقبة داخلية تتحقق كل ساعة من أن نموذج التقديم على بوابته يعمل كما هو متوقع، وأن شبكة BLS تُعرض وتُقبل بشكل سليم. النموذج الواحد يعني مهمة واحدة في اللحظة، فتكفيه خطة BASIC بسعر 15 دولاراً شهرياً مع 5 threads وعدد حلول غير محدود لكل thread.

عندما يتوسع الفريق ويشغّل الفحص على عدة بيئات (اختبار، تجريبي، إنتاج) وبلغات واجهة مختلفة بالتوازي، يصبح السقف هو عدد الـ threads لا عدد الحلول: خطة ADVANCE بسعر 90 دولاراً شهرياً تمنح 50 thread متزامناً. القاعدة العملية بسيطة — احسب أعلى عدد من عمليات الحل المتزامنة في ساعة الذروة لديك (عادة بداية الدوام بتوقيت القاهرة والرياض، حين تتراكم الطلبات)، وليس متوسط اليوم كله. الأسعار تُحتسب بالدولار الأمريكي بغض النظر عن بلد التشغيل.


ضبط المهلات وإعادة المحاولة

  • لا تستطلع قبل الثانية الخامسة. الاستطلاع المبكر يستهلك طلبات دون فائدة ويعيد CAPCHA_NOT_READY فقط.
  • اجعل سقف الحلقة زمنياً لا عددياً. ثلاثون دورة بفاصل خمس ثوانٍ تعني مهلة انتهاء قدرها 150 ثانية؛ اربطها بمهلة السكربت الكلية حتى لا تتعلق العملية.
  • أعد المحاولة من الخطوة 1 لا من الخطوة 3. إذا انتهت المهلة فالشبكة على الصفحة غالباً تغيّرت؛ أعد التقاط الصور ورمز التعليمات من جديد.
  • استخدم التراجع الأسي عند أخطاء الشبكة. خطأ اتصال عابر لا يستحق إسقاط الدورة كاملة.
  • افصل سجل الأخطاء عن سجل النجاح. رمز الخطأ ومعرّف المهمة معاً يكفيان لتشخيص معظم الحالات دون إعادة تشغيل السكربت.

بحسب أرقام السرعة المنشورة، يعالج محرك BLS المهمة في أقل من ثانية واحدة بمعدل نجاح مرتفع؛ الوقت الإضافي الذي تراه في سكربتك هو زمن رفع الصور التسع ودورة الاستطلاع التي اخترتها أنت.


الأخطاء الشائعة ومعالجتها

رمز الخطأ السبب المعالجة
ERROR_BAD_PARAMETERS صور ناقصة أو رمز تعليمات غير صالح أرسل الصور التسع كاملة مع رمز رقمي صحيح
CAPCHA_NOT_READY المهمة ما تزال قيد المعالجة تابع الاستطلاع الدوري كل 5 ثوانٍ ضمن سقف المهلة
ERROR_ZERO_BALANCE الرصيد أو الـ threads غير كافية اشحن الرصيد أو قلّل التزامن ثم أعد المحاولة
ERROR_WRONG_USER_KEY صيغة المفتاح غير صحيحة — يجب أن يكون 32 حرفاً تحقق من نسخ المفتاح كاملاً بلا مسافات
ERROR_KEY_DOES_NOT_EXIST المفتاح غير موجود انسخ المفتاح من لوحة التحكم مرة أخرى
ERROR_ZERO_CAPTCHA_FILESIZE حمولة الصورة أصغر من 100 بايت تأكد أن src حُمّل فعلياً قبل الترميز
ERROR_WRONG_FILE_EXTENSION امتداد غير مدعوم استخدم jpg أو jpeg أو png أو gif
IP_BANNED محاولات اعتماد خاطئة متكررة انتظر نحو 5 دقائق وأرسل بيانات اعتماد صحيحة

قائمة تحقق قبل تشغيل سكربت BLS في الإنتاج

  • مفتاح الـ API يُقرأ من متغيّر بيئة، ولا يظهر في أي سجل.
  • عدد الصور المرسلة يُتحقق منه برمجياً قبل الإرسال.
  • رمز التعليمات يُقرأ في الدورة نفسها التي التُقطت فيها الصور.
  • كل خطأ غير CAPCHA_NOT_READY يوقف الحلقة فوراً.
  • المتصفح يُغلق في كتلة finally حتى عند فشل الدورة.

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

هل يجب إرسال الصور التسع دائماً حتى لو بدت بعضها فارغة؟

نعم. طريقة bls تتوقع الشبكة كاملة بالترتيب الأصلي، لأن الأرقام المعادة تشير إلى مواضع داخل هذه الشبكة. إرسال ثماني صور يعيد غالباً ERROR_BAD_PARAMETERS.

كم عدد الـ threads الذي أحتاجه لتشغيل عدة نماذج بالتوازي؟

عدد الـ threads يساوي عدد عمليات الحل الجارية في اللحظة نفسها. نموذجان يعملان بالتوازي يحتاجان thread اثنين فقط، وليس ثمانية لأن كلاً منهما يرسل تسع صور — الصور التسع مهمة واحدة.

ماذا أفعل إذا أُعيد تحميل الشبكة بعد وصول النتيجة؟

اعتبر النتيجة منتهية الصلاحية وابدأ من جديد: التقط رمز التعليمات والصور مرة أخرى ثم أرسل مهمة جديدة. أرقام الخلايا مرتبطة بالشبكة التي أُرسلت، لا بالصفحة بعد تحديثها.

هل يعمل السكربت داخل Docker أو على خادم بلا واجهة رسومية؟

نعم، مع تشغيل Puppeteer في وضع headless وتثبيت اعتماديات Chromium داخل الصورة. تفاعل CaptchaAI عبر HTTP لا يتغيّر إطلاقاً بتغيّر بيئة التشغيل.


أدلة ذات صلة


أنشئ حسابك على CaptchaAI وابدأ بحل شبكات BLS →

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