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

تقليل انقطاعات CAPTCHA في سير عمل استخراج البيانات

ظهور اختبار CAPTCHA أثناء جمع البيانات ليس صدفة، بل نتيجة أربع إشارات يقيسها الموقع قبل أن يقرر: سمعة عنوان IP، وإيقاع الطلبات، وبصمة ترويسات HTTP، وتاريخ الجلسة. اضبط هذه الإشارات بالترتيب وينخفض عدد الاختبارات التي يصادفها زاحفك من مئات إلى عشرات لكل ألف صفحة؛ أما ما يتبقّى منها فيُحلّ برمجيًا عبر CaptchaAI دون أن يتوقف السكربت في منتصف التشغيل.

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

ما الذي يشغّل اختبار CAPTCHA أصلًا؟

القرار يقوم على مزيج من الإشارات لا على واحدة:

  • سمعة عنوان IP — نطاقات مراكز البيانات مصنّفة مسبقًا لدى معظم أنظمة الحماية.
  • إيقاع الطلبات — الفواصل الزمنية المتطابقة تمامًا لا تصدر عن مستخدم بشري.
  • بصمة الترويسات — ترويسات ناقصة أو غير متسقة مع الـ User-Agent المعلن.
  • تاريخ الجلسة — طلب يصل إلى صفحة داخلية عميقة دون أي ملفات تعريف ارتباط سابقة.

والأثر تراكمي: معالجة إشارتين ضعيفتين أجدى من المبالغة في ضبط إشارة واحدة.

الطبقة الأولى: إشارات الشبكة وإيقاع الطلبات

1. استبدل عناوين مراكز البيانات بوكلاء سكنيين

عناوين مراكز البيانات تُطلق اختبارات CAPTCHA بمعدل يفوق نظيراتها السكنية بخمس إلى عشر مرات، لأنها تقع ضمن نطاقات مصنّفة سلفًا:

# Residential proxy rotation
proxies = {
    "http": "http://user:[email protected]:8080",
    "https": "http://user:[email protected]:8080"
}
resp = requests.get(url, proxies=proxies)

اجعل التدوير على مستوى الجلسة لا الطلب؛ تغيّر عنوان IP داخل جلسة مفتوحة إشارة مريبة بحد ذاتها.

2. اجعل إيقاع الطلبات غير منتظم

import random
import time

# Random delay between 3-8 seconds
time.sleep(random.uniform(3, 8))

المواقع تسجّل توقيت الطلبات، والفاصل الثابت — ثانية واحدة بالضبط بين كل طلب وآخر — من أوضح دلائل الأتمتة. التأخير العشوائي يقارب سلوك التصفح الطبيعي، ويكلّفك دقائق إضافية مقابل انخفاض ملموس في عدد الاختبارات.

الطبقة الثانية: بصمة المتصفح وتاريخ الجلسة

3. أرسل ترويسات HTTP مطابقة لمتصفح حقيقي

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Referer": "https://www.google.com/",
    "DNT": "1",
    "Connection": "keep-alive"
}

القيمة في الاتساق لا في الطول: ترويسات تعلن متصفح Chrome على Windows يجب أن تحمل قيم Accept وAccept-Language وAccept-Encoding المتوقعة منه فعلًا، وإلا صارت هي نفسها إشارة تعارض.

4. احتفظ بملفات تعريف الارتباط داخل جلسة واحدة

session = requests.Session()

# Visit homepage first to establish cookies
session.get("https://example.com")
time.sleep(2)

# Then access target pages
session.get("https://example.com/data")

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

5. ابنِ سلسلة إحالة تشبه تصفّح إنسان

المستخدم الحقيقي يصل إلى صفحة المنتج عبر مسار: صفحة رئيسية، ثم بحث، ثم نتيجة. أعِد إنتاج المسار نفسه في ترويسة Referer:

# Navigate like a human: search → results → detail
session.get("https://example.com")
time.sleep(2)
session.get("https://example.com/search?q=product", headers={"Referer": "https://example.com"})
time.sleep(3)
session.get("https://example.com/product/123", headers={"Referer": "https://example.com/search?q=product"})

الطبقة الثالثة: التوازي ونافذة التشغيل

6. خفّض عدد الطلبات المتزامنة لكل نطاق

التوازي اختبارات CAPTCHA لكل ألف صفحة السرعة
طلب واحد الأدنى بطيء
3 طلبات متزامنة منخفض معتدل
10 طلبات متزامنة مرتفع سريع
50 طلبًا متزامنًا مرتفع جدًا سريع مع احتمال حظر مؤقت

ابدأ بطلب واحد إلى ثلاثة لكل موقع، وارفع الرقم تدريجيًا مع قياس معدل الاختبارات بعد كل زيادة.

7. شغّل الزحف خارج ساعات الذروة المحلية

أنظمة الحماية أقل تشددًا في فترات انخفاض حركة المرور — ساعات الفجر ونهايات الأسبوع — إذ ترتفع حدود معدل الطلبات. حدّد الذروة بتوقيت جمهور الموقع المستهدف لا بتوقيت فريقك.

هل يوفّر الموقع API رسميًا؟

كثير من المنصات يوفّر واجهة عامة تغنيك عن قراءة HTML وعن CAPTCHA من الأساس:

المنصة الواجهة الرسمية ملاحظات
Amazon Product Advertising API تتطلب موافقة مسبقة
Google Custom Search API 100 استعلام مجاني يوميًا
Twitter/X API v2 باقات مدفوعة
Reddit Reddit API مجاني بعد تسجيل التطبيق

تحقّق من وجود API قبل بناء الزاحف؛ الوصول المعتمد أرخص وأثبت من أي طبقة وقاية.

مثال: مراقبة أسعار في متاجر عربية

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

  1. نقل مخرج الطلبات إلى وكلاء سكنيين داخل المنطقة التي يخدمها المتجر، لأن زيارة لمتجر سعودي من عنوان أوروبي تُقرأ كإشارة شاذة.
  2. خفض التوازي إلى ثلاثة طلبات لكل نطاق، وتحريك نافذة التشغيل إلى ما بين الثانية والسادسة صباحًا بتوقيت الرياض.
  3. توصيل مسار حل احتياطي عبر CaptchaAI للاختبارات المتبقية بدل إيقاف الدورة كلها.

خطة STANDARD — بسعر $30 شهريًا و15 thread — تناسب حجمًا كهذا، لأن الفوترة في CaptchaAI تقوم على عدد الـ threads المتزامنة لا على عدد عمليات الحل؛ الحد الفعلي هو كم اختبارًا تعالجه في اللحظة نفسها، لا في الشهر.

عندما لا تكفي الوقاية: حلّ ما يظهر عبر CaptchaAI

لا توجد طبقة وقاية تُنهي اختبارات CAPTCHA نهائيًا؛ على نطاق واسع تحتاج إلى الاثنين: وقاية تقلّل عددها، ومسار يتعامل مع ما يمرّ منها. النمط أدناه يكتشف وجود reCAPTCHA v2 في الاستجابة، يرسل مفتاح الموقع إلى in.php، يستطلع النتيجة من res.php، ثم يعيد إرسال الصفحة بالتوكن داخل الحقل g-recaptcha-response:

import requests
import time

API_KEY = "YOUR_API_KEY"

def scrape_with_fallback(url, session):
    resp = session.get(url)

    # If CAPTCHA appears, solve it
    if "g-recaptcha" in resp.text:
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(resp.text, "html.parser")
        site_key = soup.find("div", class_="g-recaptcha")["data-sitekey"]

        # Solve via CaptchaAI
        submit = requests.get("https://ocr.captchaai.com/in.php", params={
            "key": API_KEY, "method": "userrecaptcha",
            "googlekey": site_key, "pageurl": url
        })
        task_id = submit.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|"):
                token = result.text.split("|")[1]
                resp = session.post(url, data={"g-recaptcha-response": token})
                break

    return resp.text

نقطتان عمليتان قبل نقل هذا النمط إلى الإنتاج: احفظ مفتاح الـ API في متغيّر بيئة لا داخل الملف، وحدّد مهلة انتهاء واضحة لدورة الاستطلاع حتى لا يعلق العامل على اختبار واحد وتتراكم خلفه قائمة الانتظار.

أثر الوقاية على تكلفة حل CAPTCHA

الأرقام التالية تقديرية للمقارنة النسبية بين مستويات الضبط؛ فوترة CaptchaAI نفسها قائمة على عدد الـ threads لا على عدد عمليات الحل.

مستوى الضبط اختبارات لكل ألف صفحة التكلفة التقريبية
بلا أي إجراء وقائي ~200–500 $0.20–$0.50
ترويسات HTTP وتأخير عشوائي ~50–100 $0.05–$0.10
وكلاء سكنيون مع ترويسات مضبوطة ~10–30 $0.01–$0.03
تكوين وقائي متكامل ~5–15 $0.005–$0.015

كل انخفاض في عدد الاختبارات لكل ألف صفحة ينعكس مباشرة على عدد الـ threads التي تحتاجها وعلى زمن الدورة.

قائمة تحقق سريعة

  1. مخرج سكني مطابق للمنطقة المستهدفة، وتأخير عشوائي لا فاصل ثابت.
  2. ترويسات متسقة مع الـ User-Agent، وجلسة تبدأ من الصفحة الرئيسية.
  3. توازٍ عند 1–3 طلبات لكل نطاق، ومعدل اختبارات مُسجَّل كمقياس دائم.
  4. مسار حل احتياطي جاهز حتى لا يتحوّل اختبار واحد إلى توقف كامل.

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

كم thread أحتاج لزاحف يعالج 50 ألف صفحة يوميًا؟

العدد لا يُشتق من عدد الصفحات بل من الاختبارات المتزامنة. مع تكوين وقائي جيد يبقى المعدل في حدود عشرات الاختبارات لكل ألف صفحة، وهو حجم تستوعبه خطة STANDARD بسعر $30 شهريًا مع 15 thread. ارفع الخطة عند تراكم فعلي في قائمة الانتظار، لا استباقًا.

هل يمكن الاعتماد على CaptchaAI مع اختبار hCaptcha؟

لا، فـ hCaptcha وFunCaptcha غير مدعومين حاليًا، وGeeTest v4 مدرج ضمن "قريبًا" فقط. المدعوم يشمل reCAPTCHA v2 وv3 وCloudflare Turnstile وCloudflare Challenge وGeeTest v3 والصور والشبكات وBLS، إضافةً إلى CaptchaFox وFriendly Captcha وLemin في مرحلة beta.

ما الفرق العملي بين الوكيل السكني ووكيل مركز البيانات؟

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

هل خفض التوازي يعني تأخّر المشروع؟

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

متى أتوقف عن تحسين الوقاية وأكتفي بالحل؟

عندما تصبح كلفة الطبقة التالية أعلى من كلفة حل ما تبقّى. عند معدل قريب من 5–15 اختبارًا لكل ألف صفحة يصبح المكسب هامشيًا، ويكون استقرار الزاحف نفسه أعلى عائدًا.

أدلة ذات صلة

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