Use Cases

Automação de comparação de cotações de seguros com tratamento de CAPTCHA

CAPTCHA trava a comparação automatizada de cotações de seguro porque cada seguradora protege o motor de tarifas com reCAPTCHA v2, reCAPTCHA v3 ou CAPTCHA de imagem no envio do formulário. A saída não é desistir da automação — é resolver o desafio sem invalidar as etapas anteriores (segurado, veículo ou imóvel, cobertura). Este guia mostra onde o CAPTCHA aparece no funil de cotação, por que a sessão precisa ficar fixa do início ao fim e o código para coletar cotações de várias seguradoras com a API da CaptchaAI.


Onde o CAPTCHA aparece no funil de cotação

O ponto de disparo muda conforme o ramo. Corretoras digitais e sites de operadoras individuais colocam o CAPTCHA na etapa final — depois que o formulário já reuniu dados pessoais, veículo ou imóvel e nível de cobertura. A tabela abaixo mapeia o tipo mais comum por linha de negócio, útil para dimensionar o esforço de QA antes de escrever qualquer linha de código.

Tipo de operadora CAPTCHA Ponto de gatilho Complexidade de cotação
Seguro automóvel reCAPTCHA v2 Envio do formulário de cotação Multipasso (veículo + motorista)
Seguro saúde reCAPTCHA v2 Comparação de planos Várias etapas (dados demográficos)
Seguro residencial Imagem CAPTCHA Pesquisa de endereço Moderado
Seguro de vida reCAPTCHA v2 Calculadora de taxas Formulário simples
Seguro de viagem reCAPTCHA v2 Invisível Solicitação de orçamento Formulário simples
Seguro empresarial reCAPTCHA v3 Formulário de contato/quote Formato longo

Por que a sessão precisa ficar fixa do início ao fim

Cotação de seguro é sempre um formulário em várias etapas, e o servidor amarra cada etapa à sessão e ao IP de quem preencheu a etapa anterior. Trocar de IP no meio do fluxo — por exemplo, ao rotacionar proxy entre a etapa do veículo e a etapa de cobertura — invalida a sessão e reinicia a cotação, mesmo que o CAPTCHA final seja resolvido corretamente. Em ambiente de QA, use dados fictícios e mantenha a sessão de proxy fixa por 10 a 15 minutos; isso também facilita respeitar a LGPD, já que nenhum dado real de segurado circula pelo pipeline de teste.

Passo Dados enviados Requisito de IP
1. Informações pessoais Nome, data de nascimento, CEP Mesmo IP
2. Veículo/imóvel Ano, marca, modelo Mesmo IP
3. Seleção de cobertura Limites, franquia Mesmo IP
4. Resolver CAPTCHA Token Mesmo IP
5. Exibição de cotação N/A Mesmo IP

Coletor de cotações multioperadoras

O coletor abaixo segue as mesmas cinco etapas da tabela acima: carrega a página, envia veículo e motorista, resolve o reCAPTCHA v2 na etapa de cotação e devolve o prêmio mensal já comparado entre as operadoras. A função solve_recaptcha cobre o desafio principal; solve_image_captcha fica pronta para operadoras de seguro residencial que usam CAPTCHA de imagem na busca de endereço.

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

Rode esse coletor sempre com dados fictícios de teste — nunca com CPF, apólice ou veículo reais. O objetivo é validar o pipeline de QA (parsing de HTML, tratamento de erro por operadora, ordenação por prêmio), não coletar tarifas de clientes verdadeiros.


Comparando planos de saúde no marketplace

Marketplaces de saúde seguem a mesma lógica, só que o CAPTCHA aparece depois do envio dos dados demográficos, na etapa que libera a lista de planos. A função abaixo reaproveita InsuranceQuoteCollector, resolve o reCAPTCHA na página de resultados e extrai nome do plano, prêmio e franquia de cada cartão retornado.

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

Se a operadora trocar o HTML dos cartões de plano, ajuste apenas os seletores CSS em soup.select — a parte de resolução do CAPTCHA não muda.


Solução de problemas comuns

A maior parte das falhas em produção não vem do CAPTCHA, e sim da sessão em volta dele — a tabela reúne os sintomas mais comuns e a correção direta.

Problema Causa Correção
O formulário de cotação é redefinido no meio do fluxo IP alterado entre etapas Usar sessão de proxy fixa
"Não foi possível fornecer orçamento" Falha na validação de dados Verificar os campos obrigatórios
CAPTCHA aparece duas vezes O primeiro token expirou Resolver novamente de imediato
Prêmio retorna vazio mesmo com status 200 Seletor CSS desatualizado após mudança de layout Atualizar os seletores em _parse_quote
Taxas diferentes das manuais Diferenças de cookies e sessão Iniciar uma sessão limpa
O limitador de taxa bloqueia requisições Muitas cotações solicitadas pelo mesmo IP Desacelerar e alternar IP entre operadoras

Boas práticas para reduzir CAPTCHA repetido

  • Espace as requisições entre operadoras (5 a 10 s), como em compare_carriers.
  • Mantenha a sessão de proxy fixa da primeira à última etapa do formulário.
  • Descarte cookies e comece sessão limpa a cada ciclo — misturar sessão antiga com dados novos dispara verificação extra.
  • Acima de uma dezena de operadoras por rodada, distribua consultas entre vários workers em vez de aumentar a frequência por sessão.

Perguntas frequentes

Quantas cotações dá para coletar por seguradora sem levar bloqueio?

Na prática, 20 a 50 cotações por operadora por dia com intervalos adequados. Ultrapassar esse volume aciona limitador de taxa e CAPTCHA com mais frequência — distribua a coleta ao longo do dia, não em picos.

O hCaptcha é suportado pela CaptchaAI para formulários de seguradora?

Não. O hCaptcha ainda não é suportado pela CaptchaAI. Os tipos realmente usados nesse fluxo — reCAPTCHA v2/v3, Cloudflare Turnstile e CAPTCHA de imagem — têm cobertura total.

Quanto custa automatizar a coleta de cotações com a CaptchaAI?

Os planos cobram por thread simultânea, com solves ilimitados. O BASIC (US$ 15/mês, 5 threads) já cobre um QA testando algumas operadoras; volume maior sobe para STANDARD (US$ 30/mês, 15 threads) ou ADVANCE (US$ 90/mês, 50 threads).

Preciso usar CPF e dados reais do segurado para testar o fluxo?

Não. Use CEP, veículo e dados demográficos fictícios em ambiente de QA — o pipeline testa a resolução do CAPTCHA e a extração de dados, sem depender de informação real do segurado, o que também facilita a conformidade com a LGPD.

Dá para reaproveitar a mesma automação para seguro auto, saúde, residencial e vida?

Sim. A arquitetura de sessão fixa e resolução de CAPTCHA é igual nos quatro ramos — muda só o schema de campos (veículo, demográficos, endereço ou apólice) e, no residencial, o uso mais frequente de CAPTCHA de imagem em vez de reCAPTCHA.


Guias relacionados


Automatize a comparação de cotações de seguro em escala — crie sua chave da CaptchaAI e resolva o primeiro CAPTCHA do fluxo ainda hoje.

Os comentários estão desativados para este artigo.