Anwendungsfälle

Automatisierung des Vergleichs von Versicherungsangeboten mit CAPTCHA-Verwaltung

Ja – Angebotsstrecken über mehrere Versicherer lassen sich automatisiert testen, auch wenn Tarifrechner und Vergleichsportale mit CAPTCHAs gegen die maschinelle Angebotserfassung abgesichert sind. Der eigentliche Engpass ist selten das Formular, sondern die reCAPTCHA-v2- oder Bild-Abfrage kurz vor der Preisanzeige. CaptchaAI löst genau diese Abfragen per API und liefert das Token zurück, das Ihre QA-Automatisierung in das Formular einträgt – die mehrstufige Strecke läuft weiter, ohne dass jemand manuell klickt.

Im DACH-Markt kennen Nutzer den Ablauf von Portalen wie Check24 oder Verivox: Daten eingeben, Tarife nebeneinander sehen, den günstigsten wählen. Genau diese Vergleichslogik testen QA-Teams reproduzierbar – auf eigenen oder ausdrücklich autorisierten Angebotsworkflows. Wichtig dabei: Angebotsdaten wie Geburtsdatum, Postleitzahl oder Kfz-Merkmale sind personenbezogene Daten, und auch die IP-Adresse zählt nach DSGVO dazu. Klären Sie vor jedem Testlauf Rechtsgrundlage und Datenflüsse.


Welche CAPTCHAs auf Versicherungsseiten auftreten

Der CAPTCHA-Typ hängt von der Sparte und vom Punkt in der Strecke ab, an dem der Server die Preisberechnung schützt:

Versicherungssparte CAPTCHA-Typ Auslösepunkt Formularkomplexität
Kfz-Versicherung reCAPTCHA v2 Absenden des Angebotsformulars Mehrstufig (Fahrzeug + Fahrer)
Krankenversicherung reCAPTCHA v2 Tarifvergleich Mehrstufig (demografische Daten)
Hausratversicherung Bild-CAPTCHA Adresssuche Mittel
Lebensversicherung reCAPTCHA v2 Tarifrechner Einfaches Formular
Reiseversicherung reCAPTCHA v2 Invisible Angebotsanfrage Einfaches Formular
Gewerbeversicherung reCAPTCHA v3 Kontakt-/Angebotsformular Langes Formular

CaptchaAI deckt genau dieses Spektrum ab: reCAPTCHA v2 (inklusive Invisible), reCAPTCHA v3 und Bild- bzw. OCR-CAPTCHAs. hCaptcha und FunCaptcha gehören nicht dazu – prüfen Sie deshalb vorab im DOM, welche Abfrage ein Portal tatsächlich einsetzt, bevor Sie einen Workflow aufsetzen.


Warum Sticky Sessions bei Angebotsstrecken Pflicht sind

Ein Versicherungsangebot entsteht nie in einem einzigen Request. Der Server verknüpft jeden Schritt mit Sitzung und IP-Adresse; wechselt die IP zwischenzeitlich, verwirft er die halbfertige Strecke. Deshalb sind Sticky Sessions – eine feste IP über die gesamte Angebotsstrecke – nicht optional, sondern Voraussetzung.

Schritt Übermittelte Daten IP-Anforderung
1. Persönliche Daten Name, Geburtsdatum, Postleitzahl Gleiche IP
2. Fahrzeug/Objekt Jahr, Marke, Modell Gleiche IP
3. Auswahl des Versicherungsschutzes Deckungssummen, Selbstbehalt Gleiche IP
4. CAPTCHA lösen Token Gleiche IP
5. Angebotsanzeige Gleiche IP

Setzen Sie für Versicherungsstrecken Sticky-Proxy-Sitzungen mit einer TTL von 10–15 Minuten ein. Das reicht für eine vollständige Strecke und lässt gleichzeitig genug Zeit, das CAPTCHA-Token vor dem Absenden zu lösen.


Angebote über mehrere Versicherer einsammeln

Der folgende Sammler lädt die Angebotsseite, übermittelt Fahrzeug- und Fahrerdaten, lässt CaptchaAI das reCAPTCHA lösen und trägt das Token beim finalen Request ein. Anschließend sortiert compare_carriers die erfolgreichen Angebote nach Monatsbeitrag:

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']}")

Die feste Verzögerung von 5 Sekunden zwischen den Anbietern ist bewusst gesetzt: Sie hält die Anfragefrequenz niedrig und reduziert das Risiko, dass ein Portal-seitiger Rate-Limiter die Strecke abwürgt.


Krankenversicherungstarife vergleichen

Für Krankenversicherungen ist die Strecke fast identisch – nur die Formularfelder ändern sich. Statt Fahrzeug- und Fahrerdaten übermitteln Sie demografische Angaben und lesen anschließend die Tarifkarten aus:

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 []

Weil compare_health_plans dieselbe InsuranceQuoteCollector-Klasse nutzt, teilen sich beide Strecken die Solver-Logik. Neue Sparten – Hausrat, Leben, Reise – fügen Sie hinzu, indem Sie lediglich Felder und pageurl anpassen.


Typische Fehler und ihre Behebung

Die meisten Abbrüche in Angebotsstrecken gehen auf Sitzungs- oder IP-Probleme zurück, nicht auf das CAPTCHA selbst:

Problem Ursache Lösung
Angebotsformular setzt sich mitten in der Strecke zurück IP hat zwischen zwei Schritten gewechselt Sticky-Proxy-Sitzung verwenden
„Angebot kann nicht erstellt werden" Datenvalidierung fehlgeschlagen Pflichtfelder prüfen
CAPTCHA erscheint zweimal Erstes Token ist abgelaufen Sofort erneut lösen und absenden
Andere Tarife als bei manueller Eingabe Cookie-/Sitzungsunterschiede Mit sauberer Sitzung neu starten
Rate-Limiter blockiert Anfragen Zu viele Abfragen von einer IP Frequenz senken, IP zwischen Anbietern rotieren

Ein reCAPTCHA-Token ist nur rund 120 Sekunden gültig. Lösen Sie es deshalb erst unmittelbar vor dem finalen Request und nie auf Vorrat – sonst läuft es ab, bevor die Strecke es einlöst.


Kosten und Skalierung

CaptchaAI rechnet Thread-basiert ab – pro gleichzeitigem Thread, nicht pro gelöstem CAPTCHA. Ein Thread bearbeitet ein CAPTCHA nach dem anderen; sobald eine Lösung fertig ist, nimmt derselbe Thread sofort die nächste Abfrage. Für einen einzelnen Vergleichs-Workflow, der die Anbieter ohnehin nacheinander abarbeitet, genügt der Einstiegstarif BASIC (15 $/Monat, 5 Threads, unbegrenzte Lösungen). Wer viele Portale parallel testet, gewinnt mit ADVANCE (90 $/Monat, 50 Threads) Spielraum. Die Preise sind in US-Dollar ausgewiesen; die aktuelle Tarifübersicht finden Sie auf der CaptchaAI-Preisseite.

Praktisch heißt das: Der Durchsatz hängt nicht an einem Solve-Kontingent, sondern an Ihrer Thread-Anzahl und der Lösungszeit pro Typ. Realistisch sind pro Anbieter und Tag rund 20–50 Angebote, bevor Rate-Limiter und CAPTCHAs spürbar aggressiver reagieren.


Häufige Fragen

Welche CAPTCHA-Typen auf Versicherungsportalen unterstützt CaptchaAI?

reCAPTCHA v2 (inklusive Invisible), reCAPTCHA v3 sowie Bild- und OCR-CAPTCHAs – also genau die Typen, die auf Tarifrechnern und Vergleichsseiten üblich sind. hCaptcha und FunCaptcha werden nicht unterstützt; prüfen Sie daher vorab, welche Abfrage ein Portal tatsächlich einsetzt.

Was kostet die Automatisierung eines Angebotsvergleichs?

Die Abrechnung ist Thread-basiert, nicht pro gelöstem CAPTCHA. BASIC startet bei 15 $/Monat mit 5 parallelen Threads und unbegrenzten Lösungen; für mehr Parallelität bietet ADVANCE (90 $/Monat, 50 Threads) Reserve. Ein einzelner sequenzieller Vergleichslauf kommt in der Regel mit dem Einstiegstarif aus.

Muss ich beim Abfragen von Vergleichsportalen die DSGVO beachten?

Ja. IP-Adressen und Angebotsdaten wie Geburtsdatum, Postleitzahl oder Kfz-Merkmale gelten als personenbezogene Daten. Klären Sie vor jedem Test die Rechtsgrundlage, dokumentieren Sie Ihre Datenflüsse und beschränken Sie sich auf eigene oder ausdrücklich autorisierte Workflows.

Warum bricht ein mehrstufiger Angebotsprozess mitten in der Strecke ab?

Meist wechselt die IP-Adresse zwischen zwei Schritten. Versicherer binden jeden Formularschritt an Sitzung und IP; ein Wechsel macht die Sitzung ungültig. Eine Sticky-Session mit fester IP über 10–15 Minuten hält die gesamte Strecke zusammen.


Verwandte Leitfäden


Versicherungs-Vergleichsworkflows automatisiert testen – holen Sie sich Ihren CaptchaAI-Schlüssel und lösen Sie reCAPTCHA und Bild-CAPTCHAs direkt per API.

Kommentare sind für diesen Artikel deaktiviert.