المرجع

قياس أزمنة حل CAPTCHA عبر الأنواع المختلفة باستخدام CaptchaAI

يتراوح زمن حل CAPTCHA من أجزاء من الثانية لصور OCR البسيطة إلى ما دون الدقيقة لتحديات reCAPTCHA v2 الأصعب. لكن أي رقم تقرأه — بما في ذلك هنا — يبقى استرشاديًا حتى تقيسه بنفسك داخل بيئتك الفعلية.

ولا يكفي «المتوسط» وحده؛ فالقمم العليا (P90 وP99) تحدد إعدادات المهلة وثبات خط الأتمتة عند العمل على آلاف التحديات يوميًا. يجمع هذا المرجع أرقامًا استرشادية لكل نوع يدعمه CaptchaAI، مع سكربتات جاهزة لقياس خاص ببيئتك.

جدول أزمنة الحل المرجعية لكل نوع

الأرقام التالية تستند إلى بيانات مرصودة وتقارير مستخدمين. قد تختلف النتائج بحسب بيئة التشغيل والحجم والتوقيت.

يمثّل «السقف التعاقدي» الحد الأقصى المعلن في اتفاقية الخدمة، بينما تعكس الوسيط وP90 وP99 قياسات مرصودة مع وكلاء واقعيين. ويُقاس الزمن من الإرسال حتى استرجاع النتيجة:

نوع CAPTCHA السقف التعاقدي الوسيط P90 P99 معدل النجاح
reCAPTCHA v2 < 60 ث 12–18 ث 25 ث 40 ث مرتفع
reCAPTCHA v2 Invisible < 30 ث 10–15 ث 20 ث 28 ث مرتفع
reCAPTCHA v3 < 4 ث 1–3 ث 3 ث 4 ث مرتفع
reCAPTCHA Enterprise < 60 ث 15–25 ث 35 ث 50 ث مرتفع
Cloudflare Turnstile < 10 ث 4–8 ث 9 ث 10 ث مرتفع
GeeTest v3 < 12 ث 6–10 ث 11 ث 12 ث مرتفع
Image/OCR < 0.5 ث 0.2–0.4 ث 0.5 ث 0.8 ث مرتفع
BLS CAPTCHA < 1 ث 0.3–0.7 ث 0.9 ث 1 ث مرتفع

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

لماذا تتفاوت الأرقام من بيئة إلى أخرى؟

تتحكم في القياسات عدة عوامل رئيسية:

  • زمن الشبكة (RTT): تضيف المسافة زمن ذهاب وإياب لكل طلب؛ فـ RTT بمقدار 200 مللي ثانية يضيف نحو ثانية، ويتضخّم كلما ابتعدت المنطقة.
  • جودة الوكيل (Proxy): الوكيل السكني عادةً أسرع من وكيل مركز البيانات لأنه يثير تحديات ثانوية أقل.
  • تعقيد التحدي: يتفاوت تحدي الصور في reCAPTCHA v2 صعوبةً؛ فـ«حدّد إشارات المرور» يستغرق أطول من مجرد التحقق من مربع اختيار.
  • استراتيجية الاستطلاع: الاستطلاع السريع (كل ثانيتين) يكشف النتيجة مبكرًا لكنه يرفع عدد الطلبات، والمحافظ (كل 10 ثوانٍ) يخفّض التحميل لكنه يضيف انتظارًا.

مثال عملي: فريق في الرياض أو القاهرة يشغّل الأتمتة من خادم محلي قد يقيس إجماليًا يختلف بثانية أو ثانيتين عن خادم أوروبي. والحل هو القياس من المنطقة نفسها التي ستشغّل منها الإنتاج، ثم تحجيم عدد الـ Threads حسب الحجم — فخطة ADVANCE ($90 شهريًا، 50 Thread) تشغّل 50 تحديًا متزامنًا لتقليص الانتظار في الطوابير.

كيف تقرأ النتائج: الوسيط وP90 وP99

كل رقم يخدم قرارًا مختلفًا:

  • الوسيط — التجربة النموذجية الغالبة. اعتمده في تخطيط القدرات.
  • P90 — «أسوأ حالة» في 9 من كل 10 حلول. اعتمده في المهلة الاعتيادية.
  • P99 — الحالة الطرفية الحقيقية. اضبط أقصى مهلة أعلى منها.

ضبط فترات الاستطلاع حسب النوع

اضبط الاستطلاع لكل نوع لتكشف النتيجة مبكرًا دون إغراق الواجهة:

نوع التحدي الانتظار الأولي فاصل الاستطلاع أقصى عدد محاولات
Image/OCR 5 ث 3 ث 15
Cloudflare Turnstile 5 ث 3 ث 15
BLS CAPTCHA 5 ث 3 ث 15
reCAPTCHA v2 15 ث 5 ث 20
reCAPTCHA v3 10 ث 5 ث 20
GeeTest v3 12 ث 5 ث 20
reCAPTCHA Enterprise 15 ث 5 ث 25

سكربت القياس بلغة Python

يشغّل السكربت كل نوع عدة مرات ويحسب الوسيط وP90 ومعدل النجاح تلقائيًا؛ عدّل runs لرفع حجم العينة:

# benchmark_captchaai.py
import os
import time
import statistics
import requests

API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")

def benchmark_solve(method, params, runs=10):
    """Benchmark a CAPTCHA type over multiple runs."""
    times = []
    successes = 0

    for i in range(runs):
        start = time.time()

        # Submit
        submit_params = {"key": API_KEY, "json": "1", **params}
        resp = requests.get("https://ocr.captchaai.com/in.php",
                            params=submit_params)
        result = resp.json()

        if result.get("status") != 1:
            print(f"  Run {i+1}: Submit failed - {result.get('request')}")
            continue

        task_id = result["request"]

        # Poll
        time.sleep(10)
        solved = False
        for _ in range(30):
            poll = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": API_KEY, "action": "get",
                "id": task_id, "json": "1",
            })
            poll_result = poll.json()

            if poll_result.get("status") == 1:
                elapsed = time.time() - start
                times.append(elapsed)
                successes += 1
                solved = True
                print(f"  Run {i+1}: {elapsed:.1f}s")
                break
            if poll_result.get("request") != "CAPCHA_NOT_READY":
                print(f"  Run {i+1}: Error - {poll_result.get('request')}")
                break

            time.sleep(5)

        if not solved and poll_result.get("request") == "CAPCHA_NOT_READY":
            print(f"  Run {i+1}: Timeout")

    if times:
        return {
            "runs": runs,
            "successes": successes,
            "success_rate": f"{successes/runs*100:.0f}%",
            "median": f"{statistics.median(times):.1f}s",
            "p90": f"{sorted(times)[int(len(times)*0.9)]:.1f}s" if len(times) >= 10 else "N/A",
            "min": f"{min(times):.1f}s",
            "max": f"{max(times):.1f}s",
        }
    return {"error": "No successful solves"}

# Benchmark reCAPTCHA v2
print("=== reCAPTCHA v2 ===")
recaptcha_v2 = benchmark_solve("userrecaptcha", {
    "method": "userrecaptcha",
    "googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
    "pageurl": "https://www.google.com/recaptcha/api2/demo",
})
print(recaptcha_v2)

# Benchmark Image/OCR
print("\n=== Image CAPTCHA ===")
# Submit a base64-encoded test image
import base64
# Use a test image for benchmarking
image_result = benchmark_solve("post", {
    "method": "base64",
    "body": "BASE64_ENCODED_CAPTCHA_IMAGE",
})
print(image_result)

سكربت القياس بلغة JavaScript

النسخة نفسها بلغة JavaScript عبر Axios لمن يبني الأتمتة على Node.js:

// benchmark_captchaai.js
const axios = require('axios');

const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';

async function benchmarkSolve(params, runs = 10) {
  const times = [];
  let successes = 0;

  for (let i = 0; i < runs; i++) {
    const start = Date.now();

    // Submit
    const submit = await axios.get('https://ocr.captchaai.com/in.php', {
      params: { key: API_KEY, json: '1', ...params },
    });

    if (submit.data.status !== 1) {
      console.log(`  Run ${i + 1}: Submit failed - ${submit.data.request}`);
      continue;
    }

    // Poll
    await new Promise(r => setTimeout(r, 10000));
    let solved = false;

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

      if (poll.data.status === 1) {
        const elapsed = (Date.now() - start) / 1000;
        times.push(elapsed);
        successes++;
        solved = true;
        console.log(`  Run ${i + 1}: ${elapsed.toFixed(1)}s`);
        break;
      }
      if (poll.data.request !== 'CAPCHA_NOT_READY') {
        console.log(`  Run ${i + 1}: Error - ${poll.data.request}`);
        break;
      }
      await new Promise(r => setTimeout(r, 5000));
    }

    if (!solved) console.log(`  Run ${i + 1}: Timeout`);
  }

  if (times.length === 0) return { error: 'No successful solves' };

  times.sort((a, b) => a - b);
  return {
    runs, successes,
    successRate: `${((successes / runs) * 100).toFixed(0)}%`,
    median: `${times[Math.floor(times.length / 2)].toFixed(1)}s`,
    min: `${times[0].toFixed(1)}s`,
    max: `${times[times.length - 1].toFixed(1)}s`,
  };
}

(async () => {
  console.log('=== reCAPTCHA v2 ===');
  const v2 = await benchmarkSolve({
    method: 'userrecaptcha',
    googlekey: '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
    pageurl: 'https://www.google.com/recaptcha/api2/demo',
  });
  console.log(v2);

  console.log('\n=== Cloudflare Turnstile ===');
  const turnstile = await benchmarkSolve({
    method: 'turnstile',
    sitekey: 'YOUR_TURNSTILE_SITEKEY',
    pageurl: 'https://example.com',
  });
  console.log(turnstile);
})();

أخطاء شائعة وحلولها

العَرَض السبب المحتمل الإجراء
أزمنة أبطأ من الجدول زمن شبكة مرتفع أو وكيل بطيء اختبر من منطقة أقرب وكرّر في توقيت مختلف
تباين كبير بين تشغيل وآخر تفاوت في صعوبة التحدي أو الوكلاء ارفع العينة إلى 50 تشغيلًا وافصل القياس حسب النوع
كثرة حالات انتهاء المهلة مفتاح موقع (sitekey) أو عنوان صفحة غير صحيح تحقّق من المعلمات باختبار يدوي واحد أولًا
ظهور ERROR_ZERO_BALANCE الرصيد لا يكفي لكل عمليات التشغيل اشحن الرصيد قبل قياس واسع

أسئلة شائعة

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

السقف التعاقدي هو أطول زمن ينبغي ألا تتجاوزه الخدمة، أما الوسيط فهو الزمن النموذجي في معظم الحلول وهو أقل بكثير. خطّط على الوسيط واضبط المهلات على القمم.

هل يمكنني قياس الأنواع في مرحلة beta مثل CaptchaFox؟

تدعم CaptchaAI أنواعًا في مرحلة beta مثل CaptchaFox وFriendly Captcha وLemin، ويمكنك تشغيل السكربت نفسه عليها. لكن لا توجد أرقام أداء منشورة لها بعد، فاعتبر أي قياس مؤشرًا أوليًا لا معيارًا ثابتًا.

كيف أحوّل النتائج إلى قيم مهلة في الإنتاج؟

استخدم P90 للمهلة الاعتيادية وP99 للقصوى، وأضف هامشًا بنحو 20% لتذبذب الشبكة حتى لا تُنهي مهامًا كانت ستنجح.


الخطوات التالية

أدلة ذات صلة

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