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

أتمتة إرسال النماذج مع التعامل مع CAPTCHA

أتمتة عمليات إرسال النماذج التي تتضمن تحديات CAPTCHA باستخدام Selenium وCaptchaAI.


التحدي

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


الهندسة المعمارية

┌────────────┐     ┌──────────────┐     ┌────────────┐     ┌──────────────┐
│ Load Form  │────▶│ Fill Fields  │────▶│ Detect &   │────▶│ Submit Form  │
│ (Selenium) │     │              │     │ Solve      │     │              │
│            │     │              │     │ CAPTCHA    │     │              │
└────────────┘     └──────────────┘     └────────────┘     └──────────────┘

المكونات الأساسية

حلّال CAPTCHA

import time
import requests


class FormCaptchaSolver:
    BASE = "https://ocr.captchaai.com"

    def __init__(self, api_key):
        self.api_key = api_key

    def solve(self, params, initial_wait=10):
        params["key"] = self.api_key
        params["json"] = 1
        resp = requests.post(f"{self.BASE}/in.php", data=params).json()
        if resp["status"] != 1:
            raise Exception(f"Submit error: {resp['request']}")

        task_id = resp["request"]
        time.sleep(initial_wait)

        for _ in range(60):
            result = requests.get(
                f"{self.BASE}/res.php",
                params={"key": self.api_key, "action": "get", "id": task_id, "json": 1},
            ).json()
            if result["request"] == "CAPCHA_NOT_READY":
                time.sleep(5)
                continue
            if result["status"] == 1:
                return result["request"]
            raise Exception(f"Solve error: {result['request']}")
        raise TimeoutError("CAPTCHA solve timed out")

كاشف CAPTCHA

import re
from selenium.webdriver.common.by import By


class CaptchaDetector:
    def __init__(self, driver):
        self.driver = driver

    def detect(self):
        """Detect CAPTCHA type on current page."""
        html = self.driver.page_source

        # Turnstile
        turnstile = self.driver.find_elements(By.CSS_SELECTOR, ".cf-turnstile, [data-sitekey]")
        for el in turnstile:
            if "cf-turnstile" in (el.get_attribute("class") or ""):
                return "turnstile", el.get_attribute("data-sitekey")

        # reCAPTCHA
        recaptcha = self.driver.find_elements(By.CSS_SELECTOR, "[data-sitekey]")
        if recaptcha:
            sitekey = recaptcha[0].get_attribute("data-sitekey")
            if "recaptcha" in html.lower():
                return "recaptcha_v2", sitekey

        # Image CAPTCHA
        img = self.driver.find_elements(By.CSS_SELECTOR, "img[src*='captcha'], img.captcha")
        if img:
            return "image", img[0].get_attribute("src")

        return "none", None

أتمتة النموذج

import base64
import requests as req
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class FormAutomator:
    def __init__(self, api_key):
        self.solver = FormCaptchaSolver(api_key)
        self.driver = webdriver.Chrome()
        self.detector = CaptchaDetector(self.driver)

    def fill_field(self, selector, value):
        field = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, selector))
        )
        field.clear()
        field.send_keys(value)

    def select_option(self, selector, value):
        from selenium.webdriver.support.ui import Select
        select = Select(self.driver.find_element(By.CSS_SELECTOR, selector))
        select.select_by_value(value)

    def solve_captcha(self):
        captcha_type, data = self.detector.detect()
        page_url = self.driver.current_url

        if captcha_type == "recaptcha_v2":
            token = self.solver.solve({
                "method": "userrecaptcha",
                "googlekey": data,
                "pageurl": page_url,
            })
            self.driver.execute_script(
                f'document.querySelector("[name=g-recaptcha-response]").value = "{token}";'
            )
            return True

        if captcha_type == "turnstile":
            token = self.solver.solve({
                "method": "turnstile",
                "sitekey": data,
                "pageurl": page_url,
            })
            self.driver.execute_script(
                f'document.querySelector("[name=cf-turnstile-response]").value = "{token}";'
            )
            return True

        if captcha_type == "image":
            img_data = req.get(data).content
            img_b64 = base64.b64encode(img_data).decode()
            text = self.solver.solve({"method": "base64", "body": img_b64})
            captcha_input = self.driver.find_element(
                By.CSS_SELECTOR, "input[name*='captcha']"
            )
            captcha_input.clear()
            captcha_input.send_keys(text)
            return True

        return False  # No CAPTCHA detected

    def submit_form(self, url, fields, submit_selector="button[type='submit']"):
        """
        fields: list of (selector, value) tuples
        """
        self.driver.get(url)

        for selector, value in fields:
            self.fill_field(selector, value)

        self.solve_captcha()

        submit = self.driver.find_element(By.CSS_SELECTOR, submit_selector)
        submit.click()

        return self.driver.current_url

    def close(self):
        self.driver.quit()

مثال كامل: نموذج الاتصال

automator = FormAutomator("YOUR_API_KEY")

try:
    result_url = automator.submit_form(
        url="https://example.com/contact",
        fields=[
            ("#name", "John Doe"),
            ("#email", "john@example.com"),
            ("#subject", "Sales inquiry"),
            ("#message", "I'd like to learn more about your services."),
        ],
        submit_selector="#submit-btn",
    )
    print(f"Form submitted. Redirected to: {result_url}")
finally:
    automator.close()

التعامل مع أنواع النماذج المتعددة

نموذج تسجيل الدخول

result = automator.submit_form(
    url="https://example.com/login",
    fields=[
        ("#username", "testuser"),
        ("#password", "testpass123"),
    ],
    submit_selector="#login-btn",
)

استمارة التسجيل

result = automator.submit_form(
    url="https://example.com/register",
    fields=[
        ("#first-name", "Jane"),
        ("#last-name", "Smith"),
        ("#email", "jane@example.com"),
        ("#password", "SecurePass!123"),
        ("#confirm-password", "SecurePass!123"),
    ],
    submit_selector="#register-btn",
)

نموذج البحث مع CAPTCHA

result = automator.submit_form(
    url="https://example.com/search",
    fields=[
        ("#query", "python developer"),
        ("#location", "San Francisco"),
    ],
    submit_selector="#search-btn",
)

استكشاف الأخطاء وإصلاحها

المشكلة السبب الإجراء
تم رفض الرمز انتهت صلاحية الرمز قبل الإرسال حلّ CAPTCHA آخر خطوة، ثمّ أرسل فورًا
لم يتم العثور على الحقل تحميل ديناميكي متأخر أضف انتظارًا صريحًا قبل محاولة تعبئة الحقل
تم كشف نوع CAPTCHA خاطئ عناصر CAPTCHA متعددة في الصفحة تحقّق من ترتيب منطق الكشف
يعيد النموذج تحميل نفسه بعد الإرسال فشل التحقق من جانب الخادم تحقّق من جميع الحقول المطلوبة
لم يتم تشغيل رد اتصال reCAPTCHA يجب استدعاء دالة رد الاتصال استخدم grecaptcha.execute() بعد الحقن

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

هل يمكنني إرسال النماذج بدون متصفح؟

بالنسبة إلى reCAPTCHA وTurnstile، يمكنك حل اختبارات CAPTCHA بدون متصفح وإرسالها عبر HTTP POST. ولكن إذا كان النموذج يستخدم التحقق من صحة JavaScript، فستكون هناك حاجة إلى متصفح.

كيف يمكنني التعامل مع النماذج ذات اختبارات CAPTCHA المتعددة؟

تعرض بعض النماذج اختبار CAPTCHA فقط بعد فشل التحقق من الصحة. قم بتشغيل solve_captcha() مرة أخرى بعد كل محاولة إرسال.

ماذا عن نماذج أجاكس؟

بالنسبة لعمليات إرسال AJAX، اعترض طلب XHR وقم بتضمين رمز CAPTCHA المميز في حمولة الطلب بدلاً من ملء حقل مخفي.


أدلة ذات صلة


أتمتة أي نموذج — حل اختبار CAPTCHA باستخدام CaptchaAI.

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