حالات الاستخدام

البرامج النصية لأتمتة CAPTCHA مع CaptchaAI

يحوّل كل سكربت في هذه الصفحة اختبار CAPTCHA إلى رمز جاهز للحقن في نموذجك عبر دورة بسيطة: أرسل الطلب، استطلع النتيجة، ثم استخدم الرمز. جمعنا ستة سكربتات جاهزة للنسخ تغطي أكثر الحالات شيوعاً في العمل اليومي: reCAPTCHA v2، وCloudflare Turnstile، واختبارات الصور، والحل الدُفعي المتوازي، ومُحلّل شامل بلغة Node.js، وسكربت للتحقق من الرصيد. جميعها يعتمد على واجهة CaptchaAI API، ويعمل أداةً مستقلة من سطر الأوامر أو وحدةً تستوردها داخل مشروعك القائم.

النمط المشترك خلف كل سكربت

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

  1. الإرسال: ترسل نوع الاختبار وبياناته — مثل مفتاح الموقع وعنوان الصفحة — إلى نقطة النهاية in.php، فتعيد لك استجابة على هيئة OK|<task_id>.
  2. حفظ المعرّف: تستخرج task_id من الاستجابة، وهو المفتاح الذي تستفسر به عن النتيجة لاحقاً.
  3. الاستطلاع الدوري: تسأل نقطة النهاية res.php كل خمس ثوانٍ عن حالة المهمة، وطالما تعيد CAPCHA_NOT_READY يستمر الانتظار.
  4. استخدام الرمز: عند اكتمال الحل تصل استجابة OK|<token>، فتحقن هذا الرمز في الحقل المخصّص داخل النموذج قبل إرساله.

بمجرد استيعاب هذه الدورة، تصبح كل السكربتات التالية اختلافات بسيطة حول النمط نفسه: يتغيّر الوسيط والمعاملات فقط بحسب نوع الاختبار.

السكربت 1: حل reCAPTCHA v2

هذا السكربت هو نقطة البداية الأكثر طلباً، إذ يظهر reCAPTCHA v2 على شاشات تسجيل الدخول ونماذج التسجيل في معظم المواقع. يستقبل مفتاح الموقع وعنوان الصفحة وسيطين من سطر الأوامر، يطبع معرّف المهمة، ثم يطبع نقطة عند كل دورة انتظار حتى يصل الرمز، ما يمنحك مؤشراً بصرياً على التقدم. لاحظ أنه يحاول حتى 60 مرة بفاصل خمس ثوانٍ، أي مهلة قصوى تقارب خمس دقائق قبل أن يتوقف.

#!/usr/bin/env python3
"""Solve reCAPTCHA v2 and print the token."""
import requests
import time
import sys

API_KEY = "YOUR_API_KEY"

def solve_recaptcha_v2(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url
    })
    if not resp.text.startswith("OK|"):
        print(f"Error: {resp.text}", file=sys.stderr)
        sys.exit(1)

    task_id = resp.text.split("|")[1]
    print(f"Task ID: {task_id}")

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY":
            print(".", end="", flush=True)
            continue
        if result.text.startswith("OK|"):
            print()
            return result.text.split("|")[1]
        print(f"\nError: {result.text}", file=sys.stderr)
        sys.exit(1)

    print("\nTimeout", file=sys.stderr)
    sys.exit(1)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <site_key> <page_url>")
        sys.exit(1)
    token = solve_recaptcha_v2(sys.argv[1], sys.argv[2])
    print(token)

طريقة التشغيل من الطرفية:

python solve_recaptcha.py "6Le-wvkS..." "https://example.com/form"

السكربت 2: حل Cloudflare Turnstile

يشبه Turnstile سابقه في طريقة الاستدعاء، لكنه يعتمد الوسيط turnstile والمعامل sitekey بدل googlekey. ينتشر هذا الاختبار في المواقع التي تعتمد شبكة Cloudflare، ويميل إلى الحل بسرعة. كُتبت النسخة هنا مختصرة عمداً لتعمل وحدةً قابلة للاستيراد داخل مشاريعك مباشرة.

#!/usr/bin/env python3
"""Solve Cloudflare Turnstile and print the token."""
import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_turnstile(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": site_key,
        "pageurl": page_url
    })
    task_id = resp.text.split("|")[1]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

token = solve_turnstile("0x4AAAAA...", "https://example.com")
print(token)

السكربت 3: حل اختبار CAPTCHA للصور

حين يكون الاختبار صورة نصية بسيطة — أحرف مشوّهة مثلاً — لا تحتاج إلى مفتاح موقع إطلاقاً. يقرأ هذا السكربت الصورة من ملف محلي أو من رابط، يحوّلها إلى ترميز Base64، ثم يرسلها بالوسيط base64. المهلة هنا أقصر، إذ تكفي غالباً ثلاثون دورة انتظار لأن حل الصور أسرع من الاختبارات التفاعلية.

#!/usr/bin/env python3
"""Solve an image CAPTCHA from a file or URL."""
import requests
import base64
import time
import sys

API_KEY = "YOUR_API_KEY"

def solve_image(image_source):
    # Load image
    if image_source.startswith("http"):
        img_data = requests.get(image_source).content
    else:
        with open(image_source, "rb") as f:
            img_data = f.read()

    img_b64 = base64.b64encode(img_data).decode()

    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "base64",
        "body": img_b64
    })
    task_id = resp.text.split("|")[1]

    for _ in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

if __name__ == "__main__":
    text = solve_image(sys.argv[1])
    print(text)

طريقة التشغيل من الطرفية:

python solve_image.py captcha.png
python solve_image.py "https://example.com/captcha.jpg"

السكربت 4: الحل الدُفعي المتوازي

إذا كان أمامك عشرات الاختبارات في وقت واحد — صفحات متعددة ضمن جلسة استخراج بيانات مصرّح بها مثلاً — فتشغيلها تِباعاً يهدر الوقت. يستخدم هذا السكربت ThreadPoolExecutor لتشغيل عدة عمليات حل بالتوازي، ويعيد قائمة منظّمة تحمل حالة كل مهمة: ناجحة أو فاشلة. عدد العمليات المتوازية مضبوط عبر max_workers، ويجب ألا يتجاوز عدد الخيوط — threads — المتاح في خطتك.

#!/usr/bin/env python3
"""Solve multiple CAPTCHAs concurrently."""
import requests
import time
from concurrent.futures import ThreadPoolExecutor, as_completed

API_KEY = "YOUR_API_KEY"

def solve_one(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY, "method": "userrecaptcha",
        "googlekey": site_key, "pageurl": page_url
    })
    task_id = resp.text.split("|")[1]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

def solve_batch(tasks, max_workers=5):
    """
    tasks: list of (site_key, page_url) tuples
    Returns: list of tokens
    """
    results = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {
            executor.submit(solve_one, sk, url): (sk, url)
            for sk, url in tasks
        }
        for future in as_completed(futures):
            sk, url = futures[future]
            try:
                token = future.result()
                results.append({"url": url, "token": token, "status": "ok"})
            except Exception as e:
                results.append({"url": url, "error": str(e), "status": "failed"})
    return results

# Example
tasks = [
    ("6Le-wvkS...", "https://example.com/page1"),
    ("6Le-wvkS...", "https://example.com/page2"),
    ("6Le-wvkS...", "https://example.com/page3"),
]
results = solve_batch(tasks)
for r in results:
    print(f"{r['url']}: {r['status']}")

السكربت 5: مُحلّل شامل بلغة Node.js

لمن يعمل في بيئة JavaScript، يوفّر هذا المُحلّل دالة واحدة تقبل أي مجموعة معاملات وتعمل مع أي نوع مدعوم من الاختبارات. مرّر إليها الوسيط والمفاتيح المناسبة، فتتكفّل بالإرسال والاستطلاع حتى تعيد الرمز. يمكن استيرادها عبر module.exports في أي مشروع Node.js قائم دون تعديل يذكر.

#!/usr/bin/env node
// Solve any CAPTCHA type from the command line
const axios = require("axios");

const API_KEY = "YOUR_API_KEY";

async function solve(params) {
  params.key = API_KEY;
  const submit = await axios.get("https://ocr.captchaai.com/in.php", {
    params,
  });
  if (!submit.data.startsWith("OK|")) throw new Error(submit.data);
  const taskId = submit.data.split("|")[1];

  while (true) {
    await new Promise((r) => setTimeout(r, 5000));
    const result = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: taskId },
    });
    if (result.data === "CAPCHA_NOT_READY") continue;
    if (result.data.startsWith("OK|")) return result.data.split("|")[1];
    throw new Error(result.data);
  }
}

// Usage examples:
// Solve reCAPTCHA v2
// solve({ method: "userrecaptcha", googlekey: "SITE_KEY", pageurl: "URL" })

// Solve Turnstile
// solve({ method: "turnstile", sitekey: "SITE_KEY", pageurl: "URL" })

module.exports = { solve };

سكربت التحقق من الرصيد

قبل تشغيل دفعة كبيرة، تحقّق من رصيدك حتى لا تتوقف المهام في منتصف الطريق. يستدعي هذا السكربت المختصر الإجراء getbalance عبر res.php ويطبع الرصيد المتبقي بالدولار.

#!/usr/bin/env python3
"""Check CaptchaAI account balance."""
import requests

API_KEY = "YOUR_API_KEY"

resp = requests.get("https://ocr.captchaai.com/res.php", params={
    "key": API_KEY,
    "action": "getbalance"
})
print(f"Balance: ${resp.text}")

سيناريو عملي من السوق

تخيّل فريق ضمان الجودة في متجر إلكتروني بالرياض يشغّل اختبارات ليلية على مسار إتمام الشراء المحمي بـ Cloudflare Turnstile. بدل تعطيل هذا المسار أثناء الاختبار، يستدعي الفريق السكربت الثاني للحصول على رمز صالح، ثم يُكمل سيناريو الشراء آلياً على بيئة مملوكة للفريق. وحين تتضاعف الاختبارات قبل موسم التخفيضات، يتحوّلون إلى السكربت الدُفعي لتشغيل عشرات المسارات بالتوازي ضمن حدود الخيوط في خطتهم. هذا النمط — أتمتة موثوقة على بيئة مصرّح بها — هو الاستخدام المقصود من هذه السكربتات.

نصائح للتشغيل في الإنتاج

السكربتات أعلاه مكتوبة لتكون واضحة ومقروءة، لكن التشغيل في الإنتاج يطلب طبقة إضافية من المتانة:

  • أضف معالجة صريحة لكل رمز خطأ يعيده res.php، مثل نفاد الرصيد أو انتهاء المهلة، ثم سجّل الحالة للمراجعة لاحقاً.
  • طبّق إعادة المحاولة مع التراجع الأسي عند الأخطاء المؤقتة بدل إعادة الإرسال الفوري الذي يضاعف الحِمل.
  • لا تضع مفتاح الـ API داخل الشيفرة؛ حمّله من متغيّر بيئة أو من خزنة أسرار.
  • راقب معدل الطلبات لتبقى ضمن عدد الخيوط المتاح في خطتك وتتجنّب الاختناق.

التكلفة ونموذج الخطط

يحاسبك CaptchaAI على أساس عدد الخيوط المتزامنة — threads — لا على أساس كل عملية حل، وكل خطة تشمل عدداً غير محدود من عمليات الحل خلال الشهر. تبدأ الخطط من BASIC بسعر 15 دولاراً شهرياً مقابل 5 خيوط، وترتفع إلى ENTERPRISE بسعر 300 دولاراً شهرياً مقابل 200 خيط، وصولاً إلى VIP-3 بسعر 7,500 دولاراً مقابل 5,000 خيط للأحجام الكبيرة جداً. عملياً، يحدّد عدد الخيوط كم عملية حل تستطيع تشغيلها بالتوازي عبر السكربت الدُفعي، من دون فاتورة تتضخم مع كل اختبار.

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

هل تحلّ هذه السكربتات اختبارات hCaptcha أو FunCaptcha؟

لا. لا يشمل دعم CaptchaAI حالياً hCaptcha ولا FunCaptcha — أي Arkose Labs — لذا لن تعمل هذه السكربتات معهما. أمّا الأنواع المدعومة فتشمل reCAPTCHA v2 وv3 وCloudflare Turnstile وCloudflare Challenge وGeeTest v3 واختبارات الصور والشبكة وBLS، إضافة إلى دعم تجريبي بمرحلة beta لكل من CaptchaFox وFriendly Captcha وLemin.

كيف أتعامل مع رموز الأخطاء ومهلة الانتظار؟

تعيد نقطة النهاية res.php رمز خطأ نصياً عند وجود مشكلة، مثل نفاد الرصيد أو مفتاح API غير صالح. تلتقط السكربتات هذه الحالة وتوقف التنفيذ مع طباعة الرسالة. في الإنتاج، استبدل الإيقاف الفوري بإعادة محاولة محدودة، وميّز بين خطأ مؤقت يستدعي إعادة المحاولة وخطأ نهائي يستدعي التوقف. أمّا مهلة الانتظار فتُضبط عبر عدد الدورات — 60 دورة في سكربت reCAPTCHA و30 في سكربت الصور — وارفعها أو اخفضها حسب سرعة النوع الذي تحلّه.

ما الفرق بين الاستطلاع الدوري وطريقة رد النداء؟

تعتمد هذه السكربتات على الاستطلاع الدوري: تسأل الخادم عن النتيجة كل خمس ثوانٍ حتى تجهز. البديل هو رد النداء — Callback — حيث يرسل الخادم النتيجة إلى نقطة نهاية لديك فور جهوزها، ما يوفّر طلبات الاستطلاع المتكررة. الاستطلاع أبسط في السكربتات القصيرة والتشغيل المحلي، بينما يناسب رد النداء الأنظمة الخادمية التي تعالج أحجاماً كبيرة.

كم طلباً متزامناً أستطيع تشغيله؟

يحدّه عدد الخيوط — threads — في خطتك، لأن كل خيط يمثّل اختباراً واحداً قيد المعالجة في اللحظة نفسها. اضبط max_workers في السكربت الدُفعي على قيمة لا تتجاوز خيوط خطتك؛ فخطة بها 50 خيطاً تتيح خمسين عملية حل متوازية، ومتى انتهى خيط تحرّر فوراً للمهمة التالية.

كيف أدمج هذه السكربتات في مشروعي الحالي؟

كل سكربت مصمّم ليعمل أداةً مستقلة من سطر الأوامر ووحدةً قابلة للاستيراد في آن واحد. استورد دوال الحل مباشرة — مثل solve_turnstile أو solve_batch — واستدعِها من داخل شيفرتك بدل تشغيل الملف كاملاً. في Node.js استعمل module.exports المصدّر في السكربت الخامس.

أدلة ذات صلة

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