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

أتمتة البوابات الحكومية وحل اختبارات CAPTCHA برمجياً

لأتمتة أي بوابة حكومية تحجب نماذجها خلف اختبار CAPTCHA، تحتاج إلى ثلاثة عناصر تعمل معاً:

  1. جلسة ثابتة تحافظ على نفس عنوان IP.
  2. مزوّد حل يتعامل مع نوع الكابتشا المستخدم.
  3. ترتيب دقيق يضع الحل قبل الإرسال مباشرة.

هذا الدليل يجمع هذه العناصر باستخدام CaptchaAI لأكثر أنواع البوابات شيوعاً: مواعيد التأشيرات مثل BLS، وسجلات المحاكم، وبوابات التصاريح، والسجلات العقارية العامة.

هذا المسار يومي لفرق ضمان الجودة، ومطوّري التكنولوجيا المدنية، والمهنيين القانونيين. فمقدّم الطلب في الخليج الذي يحجز موعد تأشيرة عبر مركز BLS، أو الموظف الذي يستعلم عن حالة معاملة في بوابة حكومية، يصطدم بنفس اختبارات CAPTCHA التي تُبطئ الأتمتة. الهدف ليس الالتفاف على الحماية، بل حلّ الاختبار المطلوب ضمن سير عمل مصرّح به على نماذجك أو بيانات مسموح لك بالوصول إليها.


متى تكون أتمتة البوابات الحكومية مناسبة

قبل كتابة أول سطر، تأكد أن استخدامك مشروع. الحالات المقبولة تشمل:

  • أتمتة نماذجك الخاصة.
  • الاستعلام عن بيانات عامة متاحة.
  • اختبار ضمان الجودة لتطبيق تملكه.

راجع شروط خدمة كل بوابة أولاً.

بعد ذلك، ثبّت جلستك: معظم البوابات تتحقق من تناسق عنوان IP بين صفحات النموذج، وتفرض مهلة قصيرة للجلسة. وكيل سكني ثابت مع ترويسة User-Agent واقعية يقلّل حالات الحظر. هذان الأساسان يتكرران في كل مثال أدناه.


خريطة اختبارات CAPTCHA حسب نوع البوابة

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

فئة البوابة اختبار CAPTCHA الشائع مواقع المثال حالة الاستخدام
التأشيرة / الهجرة بلس، reCAPTCHA v2 بوابات BLS، USCIS حجز موعد
DMV / المركبات الآلية reCAPTCHA v2، الصورة مواقع DMV الحكومية تجديد التسجيل
سجلات المحكمة reCAPTCHA v2 PACER، محاكم الدولة بحث القضية
التصاريح / التراخيص صورة التحقق بوابات تصريح المدينة تقديم الطلب
بوابات الضرائب reCAPTCHA v2 IRS، مواقع الضرائب الحكومية التحقق من حالة الإقرار الضريبي
السجلات العامة صورة CAPTCHA، reCAPTCHA سجلات المقاطعة بحث Property/deed

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


حجز مواعيد تأشيرة BLS آلياً

تعتمد بوابات BLS على نظام كابتشا خاص بها. يدعم CaptchaAI اختبارات BLS بمعدل نجاح مرتفع، ويمكن حلّها كصورة عبر النقطة in.php ثم استطلاع النتيجة من res.php. الفكرة الأساسية: نزّل صورة الكابتشا، أرسلها بترميز base64، ثم استفسر عن النتيجة على فترات حتى تعود جاهزة.

الصنف التالي يغلّف الدورة كاملة — تسجيل الدخول، فحص المواعيد المتاحة، ثم الحجز — ويحلّ الكابتشا عند كل صفحة تطلبها:

import requests
import time
import base64

CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def solve_bls_captcha(captcha_image_url, session):
    """Solve BLS-specific CAPTCHA."""
    # Download CAPTCHA image
    img_resp = session.get(captcha_image_url)
    img_b64 = base64.b64encode(img_resp.content).decode()

    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "base64",
        "body": img_b64,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(30):
        time.sleep(3)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("BLS CAPTCHA timeout")


class BLSAppointmentBooker:
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
        })

    def login(self, portal_url, email, password):
        """Login to BLS portal with CAPTCHA."""
        resp = self.session.get(portal_url)

        # Extract CAPTCHA image URL from page
        import re
        match = re.search(r'src="(/captcha[^"]+)"', resp.text)
        if match:
            captcha_url = portal_url.rstrip("/") + match.group(1)
            captcha_text = solve_bls_captcha(captcha_url, self.session)
        else:
            captcha_text = ""

        login_resp = self.session.post(portal_url, data={
            "email": email,
            "password": password,
            "captcha": captcha_text,
        })
        return login_resp.status_code == 200

    def check_appointment_slots(self, slots_url):
        """Check available appointment slots."""
        resp = self.session.get(slots_url)
        if resp.status_code == 200:
            return resp.json().get("available_slots", [])
        return []

    def book_slot(self, booking_url, slot_id, applicant_data):
        """Book an appointment slot, handling any CAPTCHA."""
        resp = self.session.get(booking_url)

        # Check for CAPTCHA on booking page
        import re
        match = re.search(r'src="(/captcha[^"]+)"', resp.text)
        if match:
            captcha_url = booking_url.rstrip("/") + match.group(1)
            captcha_text = solve_bls_captcha(captcha_url, self.session)
        else:
            captcha_text = ""

        resp = self.session.post(booking_url, data={
            "slot_id": slot_id,
            "captcha": captcha_text,
            **applicant_data,
        })

        return {
            "success": resp.status_code == 200,
            "confirmation": resp.json().get("confirmation_number"),
        }

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


البحث في سجلات المحاكم عبر reCAPTCHA v2

بوابات المحاكم مثل PACER تعتمد غالباً على reCAPTCHA v2. الفرق عن كابتشا الصور أنك لا ترسل صورة، بل ترسل sitekey وعنوان الصفحة عبر method=userrecaptcha، فيعيد CaptchaAI الرمز الذي يُوضع في الحقل g-recaptcha-response. الصنف التالي يحمّل صفحة البحث، يحلّ reCAPTCHA v2، ثم يرسل الاستعلام ويحلّل جدول النتائج:

def solve_recaptcha(sitekey, pageurl):
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


class CourtRecordSearcher:
    def __init__(self, proxy=None):
        self.session = requests.Session()
        if proxy:
            self.session.proxies = {"http": proxy, "https": proxy}
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
        })

    def search_cases(self, court_url, search_params, sitekey):
        """Search court records with reCAPTCHA handling."""
        # Load search page
        self.session.get(court_url)

        # Solve CAPTCHA
        token = solve_recaptcha(sitekey, court_url)

        # Submit search with token
        resp = self.session.post(court_url, data={
            **search_params,
            "g-recaptcha-response": token,
        })

        if resp.status_code == 200:
            return self._parse_results(resp.text)
        return []

    def _parse_results(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")
        cases = []
        for row in soup.select("table.results tr")[1:]:
            cols = row.select("td")
            if len(cols) >= 4:
                cases.append({
                    "case_number": cols[0].get_text(strip=True),
                    "parties": cols[1].get_text(strip=True),
                    "date": cols[2].get_text(strip=True),
                    "status": cols[3].get_text(strip=True),
                })
        return cases

تمرير وكيل ثابت عبر معامل proxy يبقي عنوان IP نفسه بين تحميل الصفحة وإرسال البحث، وهو ما تتحقق منه بوابات المحاكم.


حل كابتشا الصور في بوابات التصاريح

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

def solve_image_captcha(image_url, session):
    """Solve image-based CAPTCHA common on local government sites."""
    img = session.get(image_url)
    img_b64 = base64.b64encode(img.content).decode()

    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "base64",
        "body": img_b64,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(20):
        time.sleep(3)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("Image CAPTCHA timeout")

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


الاستعلام الدُفعي عن السجلات العقارية

عند البحث عن عشرات العناوين، لا حاجة لحل كابتشا جديدة مع كل طلب. الدالة التالية تحلّ الرمز مرة كل خمسة طلبات، تحفظ النتائج في ملف CSV، وتضيف فاصلاً زمنياً احتراماً لحدود معدل البوابة:

import csv


def batch_property_lookup(addresses, portal_url, sitekey, output_file):
    """Look up multiple property records, solving CAPTCHA per batch."""
    session = requests.Session()
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
    })

    results = []
    for i, address in enumerate(addresses):
        try:
            # Solve CAPTCHA every 5th request (or when required)
            if i % 5 == 0:
                token = solve_recaptcha(sitekey, portal_url)

            resp = session.post(portal_url, data={
                "address": address,
                "g-recaptcha-response": token,
            })

            if resp.status_code == 200:
                results.append({
                    "address": address,
                    "data": resp.json(),
                })

            time.sleep(3)  # Be respectful

        except Exception as e:
            results.append({"address": address, "error": str(e)})

    # Save results
    with open(output_file, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=["address", "data", "error"])
        writer.writeheader()
        writer.writerows(results)

    return results

إعادة استخدام رمز واحد لعدة طلبات تخفض عمليات الحل، والفاصل الزمني يقلّل الحظر. عدّل تكرار الحل — الرقم 5 هنا — حسب صرامة البوابة.


إدارة الجلسات ومهلة انتهائها

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

نوع البوابة مهلة الجلسة توصية
بوابات التأشيرة 5-10 دقائق التدفق الكامل بسرعة
مواقع DMV 15 دقيقة حدّث ملف تعريف ارتباط الجلسة في منتصف الطريق
سجلات المحكمة 20-30 دقيقة عمليات البحث دفعة في مجموعات
بوابات الضرائب 10-15 دقيقة استخدم الوكيل اللزج، نفس IP
بوابات التصاريح 30 دقيقة احفظ التقدم في كل خطوة

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

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

المشكلة السبب الإجراء
لا يتم تحميل صورة CAPTCHA انتهت صلاحية ملف تعريف ارتباط الجلسة ابدأ جلسة جديدة
"انتهت الجلسة" أثناء النموذج استغرق وقتا طويلا لحلها الحل المسبق أو استخدام حل أسرع
إجابة CAPTCHA خاطئة صورة مشوهة الإبلاغ عن صورة سيئة عبر واجهة برمجة التطبيقات
أتمتة كتل البوابة كشف IP/UA استخدم الوكيل السكني + UA الحقيقي
خطأ في التحقق من صحة النموذج بعد اختبار CAPTCHA انتهت صلاحية الرمز من جانب الخادم حل اختبار CAPTCHA مباشرة قبل الإرسال

القاعدة العملية: إذا تكرر خطأ "انتهت الجلسة"، فالأرجح أن ترتيب خطواتك خاطئ — انقل استدعاء الحل إلى ما قبل الإرسال مباشرة.


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

ما الفرق بين method=bls وmethod=base64 عند حل كابتشا BLS؟

كلاهما يحل اختبارات BLS. استخدم method=bls للحل المباشر المخصّص لهذا النوع، بينما method=base64 يعامل التحدي كصورة عادية بترميز base64. جرّب المسار المباشر أولاً، وارجع إلى الحل بالصورة عند الحاجة.

لماذا يفشل حل CAPTCHA أحياناً على البوابات الحكومية؟

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

كيف أحافظ على ثبات عنوان IP في النماذج متعددة الخطوات؟

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

هل يدعم CaptchaAI اختبارات BLS وreCAPTCHA v2 المستخدمة في المواقع الحكومية؟

نعم. يدعم CaptchaAI اختبارات BLS وreCAPTCHA v2 وكابتشا الصور/OCR بمعدل نجاح مرتفع، وهذه هي الأنواع الأكثر انتشاراً على البوابات الحكومية. تُرسل reCAPTCHA v2 عبر method=userrecaptcha، والصور عبر method=base64.

هل تختلف مهلة الجلسة بين البوابات الحكومية؟

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


أدلة ذات صلة



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

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