Use Cases

Automatisation de la comparaison des devis d'assurance avec la gestion des CAPTCHA

Sur un comparateur d'assurance, le CAPTCHA n'apparaît presque jamais au premier écran : il attend le moment où le moteur de tarification s'apprête à révéler le prix. C'est précisément l'étape que vos scripts de test doivent franchir. CaptchaAI résout ce défi — reCAPTCHA v2 et v3, reCAPTCHA v2 Invisible et CAPTCHA image/OCR — pour que vos équipes QA valident les parcours de devis multi-assureurs sans rester bloquées à la dernière étape.


Où les CAPTCHA se déclenchent sur les sites d'assurance

Le type de défi dépend de la branche d'assurance et de l'endroit du parcours où il surgit :

Type d'assurance CAPTCHA Moment du déclenchement Complexité du devis
Auto reCAPTCHA v2 Envoi du formulaire de devis Multi-étapes (véhicule + conducteur)
Santé reCAPTCHA v2 Comparaison des régimes Multi-étapes (données démographiques)
Habitation CAPTCHA image Recherche d'adresse Modérée
Vie reCAPTCHA v2 Calculateur de taux Formulaire simple
Voyage reCAPTCHA v2 Invisible Demande de devis Formulaire simple
Professionnelle reCAPTCHA v3 Formulaire de contact/devis Formulaire long

Pourquoi les sessions persistantes sont indispensables

Un devis d'assurance ne se calcule jamais en une seule requête. Le parcours enchaîne plusieurs écrans, et le serveur les relie à une même session — donc à une même adresse IP. Changer d'IP en cours de route casse ce lien et renvoie l'utilisateur au début du formulaire. Autant poser cette contrainte avant d'écrire la moindre ligne de collecteur.

Étape Données envoyées Contrainte IP
1. Informations personnelles Nom, date de naissance, code postal Même IP
2. Véhicule / bien Année, marque, modèle Même IP
3. Choix de la couverture Plafonds, franchise Même IP
4. Résolution du CAPTCHA Token Même IP
5. Affichage du devis Même IP

Prévoyez des sessions proxy persistantes avec une durée de vie de 10 à 15 minutes : c'est l'ordre de grandeur d'un parcours de devis complet, résolution du CAPTCHA comprise.


Collecteur de devis multi-assureurs

Le collecteur ci-dessous charge la page de devis, envoie les informations véhicule puis conducteur, résout le reCAPTCHA v2 au moment d'afficher le tarif, puis récupère le prix. La méthode compare_carriers boucle sur plusieurs assureurs et classe les résultats par prime mensuelle.

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

Comparer les régimes d'assurance santé

La même logique s'applique aux places de marché santé : vous soumettez les données démographiques, vous résolvez le CAPTCHA qui protège l'affichage des régimes, puis vous parsez les cartes de résultats.

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

Cadence de collecte et volumétrie

Comptez en général 20 à 50 devis par assureur et par jour, avec des délais réalistes entre les requêtes. Au-delà, les portails durcissent leurs limiteurs de débit et déclenchent les CAPTCHA plus souvent.

Côté CaptchaAI, la facturation se fait au thread simultané et non à la résolution : un thread traite un CAPTCHA à la fois, puis enchaîne le suivant. BASIC ($15/mois, 5 threads) suffit pour tester quelques assureurs en séquentiel ; ADVANCE ($90/mois, 50 threads) permet d'interroger de nombreux assureurs en parallèle sans file d'attente.


Dépannage des parcours de devis

Problème Cause probable Correctif
Le formulaire se réinitialise en cours de parcours IP modifiée entre deux étapes Garder une session proxy persistante
Message « devis indisponible » Échec de validation des données Vérifier les champs obligatoires
Le CAPTCHA réapparaît juste après résolution Premier token expiré Résoudre de nouveau immédiatement
Tarif différent de la saisie manuelle Cookies ou session divergents Repartir d'une session propre
Requêtes bloquées par le rate limiting Trop de devis depuis la même IP Ralentir et alterner l'IP entre les assureurs

Automatisation et conformité RGPD

Les parcours de devis manipulent des données personnelles : nom, date de naissance, code postal, parfois éléments du véhicule. Dès que vous automatisez leur envoi, vous entrez dans le champ du RGPD, y compris en environnement de test. Quelques réflexes utiles :

  • Minimisez les données. N'envoyez que les champs strictement nécessaires au calcul du tarif et évitez de stocker les réponses complètes des assureurs.
  • Restez sur des périmètres autorisés. Testez vos propres parcours ou ceux pour lesquels vous disposez d'un accord — jamais les portails de tiers sans autorisation.
  • Journalisez sobrement. Conservez les codes d'erreur et les temps de réponse, pas les identités réelles ou fictives utilisées pour les essais.

CaptchaAI n'intervient que sur la résolution du défi CAPTCHA : les données du formulaire restent dans votre session et ne transitent jamais par le solveur.


FAQ

Quels CAPTCHA rencontre-t-on sur les comparateurs d'assurance ?

Le plus souvent du reCAPTCHA v2, sa variante Invisible et, sur les formulaires professionnels, du reCAPTCHA v3. Certains portails ajoutent un CAPTCHA image/OCR sur la recherche d'adresse. CaptchaAI prend en charge ces familles ; hCaptcha et FunCaptcha, en revanche, ne sont pas pris en charge.

Faut-il conserver la même IP pendant tout le parcours de devis ?

Oui. Le serveur relie chaque étape à votre session et à votre adresse IP ; changer d'IP en cours de route invalide le parcours et réinitialise le formulaire. Gardez une session proxy persistante sur toute la durée du devis.

Combien de threads CaptchaAI faut-il pour comparer plusieurs assureurs ?

Un seul thread suffit pour un parcours séquentiel. Pour interroger plusieurs assureurs en parallèle, comptez un thread par résolution simultanée : BASIC ($15/mois, 5 threads) couvre déjà quelques assureurs de front, ADVANCE ($90/mois, 50 threads) en gère beaucoup plus.

Comment limiter les données personnelles collectées ?

Ne testez que sur des comptes et des environnements autorisés, et n'injectez que les champs indispensables au devis. Documentez la base légale et la durée de conservation : la collecte de nom, de date de naissance et de code postal relève du RGPD.


Guides connexes


Comparez les devis d'assurance à grande échelle — récupérez votre clé CaptchaAI et fiabilisez vos parcours de test.

Les commentaires sont désactivés pour cet article.