Kasus Penggunaan

Otomatisasi Perbandingan Penawaran Asuransi dengan Penanganan CAPTCHA

Platform perbandingan asuransi dan halaman penawaran harga operator melindungi mesin tarif mereka dengan CAPTCHA untuk mencegah pengambilan penawaran harga secara otomatis. CaptchaAI menangani tantangan ini untuk tim QA yang menguji alur kerja asuransi dan agregator perbandingan.


CAPTCHA di Situs Asuransi

Jenis Asuransi CAPTCHA Titik Pemicu Kompleksitas Form
Asuransi mobil reCAPTCHA v2 Submit form penawaran Multi-step (kendaraan + pengemudi)
Asuransi kesehatan reCAPTCHA v2 Perbandingan paket Multi-step (demografi)
Asuransi rumah Image CAPTCHA Pencarian alamat Sedang
Asuransi jiwa reCAPTCHA v2 Kalkulator nilai Form sederhana
Asuransi perjalanan reCAPTCHA v2 Invisible Permintaan penawaran Form sederhana
Asuransi bisnis reCAPTCHA v3 Hubungi/form penawaran Form panjang

Kolektor Kutipan Multi-Pembawa

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

Perbandingan Paket Asuransi Kesehatan

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

Persyaratan Sesi

Penawaran asuransi selalu multi-step — sticky session sangat diperlukan:

Langkah Data yang Dikirim Persyaratan IP
1. Informasi pribadi Nama, DOB, zip IP yang sama
2. Kendaraan/properti Tahun, merek, model IP yang sama
3. Pemilihan coverage Limit, deductible IP yang sama
4. Solve CAPTCHA Token IP yang sama
5. Tampilan penawaran N/A IP yang sama

Gunakan sticky session proxy dengan TTL 10–15 menit untuk alur asuransi.


Pemecahan Masalah

Masalah Penyebab Solusi
Form penawaran reset di tengah alur IP berubah antar langkah Gunakan sticky session proxy
"Tidak dapat memberikan penawaran" Validasi data gagal Periksa field yang wajib diisi
CAPTCHA muncul dua kali Token pertama sudah kedaluarsa Solve ulang segera
Tarif berbeda dari manual Perbedaan cookie/session Mulai sesi bersih
Rate limiter memblokir request Terlalu banyak penawaran dari IP Perlambat, rotate IP antar carrier

Pertanyaan Umum

Berapa banyak penawaran yang bisa dikumpulkan per hari?

Biasanya 20–50 per carrier per hari dengan delay yang tepat. Melebihi angka ini akan memicu rate limiting dan CAPTCHA yang lebih agresif.

Mengapa perlu sticky session untuk asuransi?

Alur penawaran asuransi bersifat multi-step. Server mengaitkan setiap langkah ke session dan IP Anda. Mengubah IP di tengah alur akan membatalkan session.

Bisakah saya otomatisasi beberapa vertikal asuransi?

Ya. Pendekatan penanganan CAPTCHA yang sama berlaku untuk asuransi mobil, kesehatan, rumah, dan jiwa — hanya field form-nya saja yang berbeda.


Panduan Terkait

  • Sticky Session vs Rotating Session
  • Persistensi Session Browser
  • Metode Autentikasi Proxy
Komentar dinonaktifkan untuk artikel ini.