Сценарии использования

Автоматизация сравнения котировок страховых компаний с обработкой CAPTCHA

Платформы сравнения страховых услуг и страницы котировок операторов связи защищают свои системы тарифов с помощью CAPTCHA, чтобы предотвратить автоматический сбор котировок. CaptchaAI решает эти задачи для команд контроля качества, тестирующих рабочие процессы страхования и агрегаторы сравнения.


CAPTCHA на страховых сайтах

Тип оператора связи КАПЧА Триггерная точка Сложность цитаты
Автострахование reCAPTCHA v2 Отправка формы предложения Многоступенчатая (автомобиль + водитель)
Медицинское страхование reCAPTCHA v2 Сравнение планов Многоэтапный (демография)
Страхование жилья Капча изображения Поиск адреса Умеренный
Страхование жизни reCAPTCHA v2 Калькулятор ставок Простая форма
Страхование путешествий reCAPTCHA v2 Невидимый Запрос цены Простая форма
Страхование бизнеса reCAPTCHA v3 Контактная форма/quote Полная форма

Сборщик котировок с несколькими операторами связи

import requests
import time
import re
import base64

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


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")


def solve_image_captcha(image_bytes):
    img_b64 = base64.b64encode(image_bytes).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("Timeout")


class InsuranceQuoteCollector:
    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 get_auto_quote(self, carrier_url, vehicle_data, driver_data, sitekey):
        """Get auto insurance quote from a single carrier."""
        # Step 1: Load quote page
        self.session.get(carrier_url)

        # Step 2: Submit vehicle info
        resp = self.session.post(f"{carrier_url}/vehicle", data=vehicle_data)

        # Step 3: Submit driver info
        resp = self.session.post(f"{carrier_url}/driver", data=driver_data)

        # Step 4: Solve CAPTCHA on quote page
        token = solve_recaptcha(sitekey, f"{carrier_url}/quote")

        # Step 5: Get quote
        resp = self.session.post(f"{carrier_url}/quote", data={
            "g-recaptcha-response": token,
        })

        if resp.status_code == 200:
            return self._parse_quote(resp.text)
        return None

    def compare_carriers(self, carriers, vehicle_data, driver_data):
        """Compare quotes across multiple carriers."""
        quotes = []

        for carrier in carriers:
            try:
                quote = self.get_auto_quote(
                    carrier_url=carrier["url"],
                    vehicle_data=vehicle_data,
                    driver_data=driver_data,
                    sitekey=carrier["sitekey"],
                )
                quotes.append({
                    "carrier": carrier["name"],
                    "status": "success",
                    "quote": quote,
                })
            except Exception as e:
                quotes.append({
                    "carrier": carrier["name"],
                    "status": "failed",
                    "error": str(e),
                })
            time.sleep(5)  # Delay between carriers

        # Sort by price
        successful = [q for q in quotes if q["status"] == "success" and q["quote"]]
        successful.sort(key=lambda x: x["quote"].get("monthly_premium", float("inf")))

        return {
            "quotes": quotes,
            "best_rate": successful[0] if successful else None,
            "total_compared": len(carriers),
            "successful": len(successful),
        }

    def _parse_quote(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")

        premium_el = soup.select_one(".premium, .monthly-rate, .quote-amount")
        coverage_el = soup.select_one(".coverage-summary, .plan-details")

        return {
            "monthly_premium": premium_el.get_text(strip=True) if premium_el else "",
            "coverage": coverage_el.get_text(strip=True) if coverage_el else "",
        }


# Usage
collector = InsuranceQuoteCollector(
    proxy="http://user-session-abc:pass@residential.proxy.com:5000"
)

vehicle = {
    "year": "2022",
    "make": "Toyota",
    "model": "Camry",
    "vin": "",
    "mileage": "15000",
}

driver = {
    "age": "35",
    "gender": "M",
    "zip": "90210",
    "driving_record": "clean",
}

carriers = [
    {"name": "Carrier A", "url": "https://carrier-a.example.com/auto", "sitekey": "6Lc_xxx1"},
    {"name": "Carrier B", "url": "https://carrier-b.example.com/auto", "sitekey": "6Lc_xxx2"},
    {"name": "Carrier C", "url": "https://carrier-c.example.com/auto", "sitekey": "6Lc_xxx3"},
]

comparison = collector.compare_carriers(carriers, vehicle, driver)
print(f"Best rate: {comparison['best_rate']}")

Сравнение планов медицинского страхования

def compare_health_plans(marketplace_url, demographics, sitekey):
    """Compare health insurance plans on marketplace sites."""
    collector = InsuranceQuoteCollector(
        proxy="http://user-session-xyz:pass@residential.proxy.com:5000"
    )

    # Load marketplace
    collector.session.get(marketplace_url)

    # Submit demographics
    collector.session.post(f"{marketplace_url}/demographics", data=demographics)

    # Solve CAPTCHA for plan results
    token = solve_recaptcha(sitekey, f"{marketplace_url}/plans")

    resp = collector.session.post(f"{marketplace_url}/plans", data={
        "g-recaptcha-response": token,
    })

    if resp.status_code == 200:
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(resp.text, "html.parser")
        plans = []
        for card in soup.select(".plan-card, .insurance-plan"):
            plans.append({
                "name": card.select_one(".plan-name").get_text(strip=True) if card.select_one(".plan-name") else "",
                "premium": card.select_one(".premium").get_text(strip=True) if card.select_one(".premium") else "",
                "deductible": card.select_one(".deductible").get_text(strip=True) if card.select_one(".deductible") else "",
            })
        return plans

    return []

Требования к сеансу

Расценки на страхование всегда состоят из нескольких этапов: прикрепленные сеансы обязательны:

Шаг Данные отправлены Требование IP
1. Личная информация Имя, дата рождения, почтовый индекс Тот же IP-адрес
2. Транспортное средство/property Год, марка, модель Тот же IP-адрес
3. Выбор покрытия Лимиты, франшиза Тот же IP-адрес
4. Решение капчи Токен Тот же IP-адрес
5. Отображение котировок PLACEHOLDER_TOKEN Тот же IP-адрес

Используйте авторизованный сетевой выход-сессии с TTL 10–15 минут для страховых потоков.


Поиск неисправностей

Проблема Причина Исправить
Форма предложения сбрасывается в середине потока IP менялся между шагами Использовать авторизованный сетевой выход-сеанс
«Невозможно предоставить цитату» Проверка данных не удалась Проверьте обязательные поля
Капча появляется дважды Срок действия первого токена истек Решите снова немедленно
Тарифы, отличные от ручных Отличия Cookie/session Начать чистый сеанс
Ограничитель скорости блокирует запросы Слишком много цитат из IP Притормозите, поменяйте IP между операторами связи.

Часто задаваемые вопросы

Сколько котировок я могу собирать в день?

Обычно 20-50 на каждого перевозчика в день с надлежащими задержками. Превышение этого значения активирует ограничители скорости и CAPTCHA более агрессивно.

Зачем мне нужны липкие сессии для страховки?

Рабочие процессы с расценками на страхование являются многоэтапными. Сервер связывает каждый шаг с вашим сеансом и IP-адресом. Изменение IP-адреса в середине потока делает сеанс недействительным.

Могу ли я автоматизировать работу в нескольких страховых вертикалях?

Да. Тот же подход к обработке CAPTCHA работает для страхования автомобилей, здоровья, жилья и жизни — различаются только поля форм.


Связанные руководства


  • Сравните страховые расценки в масштабе —получите ключ CaptchaAIи автоматизируйте процесс котирования.*
Комментарии для этой статьи отключены.