Gửi xong biểu mẫu báo giá bảo hiểm ô tô hay y tế, bạn gần như chắc chắn gặp reCAPTCHA v2 ở bước cuối — đôi khi kèm CAPTCHA hình ảnh ở bước tra cứu địa chỉ. Đó là cách hãng bảo hiểm bảo vệ công cụ tính phí khỏi bị thu thập hàng loạt. Bài này chỉ CAPTCHA nào nằm ở đâu, vì sao phiên phải cố định xuyên suốt nhiều bước, và cách CaptchaAI xử lý phần giải cho đội QA kiểm thử tích hợp bảo hiểm.
CAPTCHA xuất hiện ở đâu trong quy trình báo giá bảo hiểm
Mỗi ngành bảo hiểm chọn một điểm chặn khác nhau, và độ phức tạp form quyết định loại CAPTCHA:
- Form nhiều bước: CAPTCHA thường nằm ở bước cuối.
- Form đơn giản: chỉ một lớp CAPTCHA duy nhất.
| Loại bảo hiểm | CAPTCHA gặp phải | Điểm kích hoạt | Độ phức tạp báo giá |
|---|---|---|---|
| Ô tô | reCAPTCHA v2 | Gửi biểu mẫu báo giá | Nhiều bước (xe + tài xế) |
| Y tế | reCAPTCHA v2 | So sánh gói bảo hiểm | Nhiều bước (nhân khẩu học) |
| Nhà ở | CAPTCHA hình ảnh | Tra cứu địa chỉ | Trung bình |
| Nhân thọ | reCAPTCHA v2 | Máy tính phí bảo hiểm | Biểu mẫu đơn giản |
| Du lịch | reCAPTCHA v2 Invisible | Yêu cầu báo giá | Biểu mẫu đơn giản |
| Doanh nghiệp | reCAPTCHA v3 | Biểu mẫu liên hệ/báo giá | Biểu mẫu dài |
Vì sao luồng báo giá nhiều bước cần phiên cố định
Quy trình báo giá hiếm khi chỉ có một bước; server gắn mỗi bước với cùng session và IP, đổi IP giữa chừng gần như luôn làm mất session. Một đội QA outsourcing ở TP.HCM kiểm thử báo giá cho khách hàng bảo hiểm Bắc Mỹ thường gặp lỗi này đầu tiên: đổi IP giữa bước "thông tin xe" và bước "chọn phạm vi" khiến phiên bị reset dù chưa gửi báo giá.
| Bước | Dữ liệu gửi | Yêu cầu IP |
|---|---|---|
| 1. Thông tin cá nhân | Họ tên, ngày sinh, mã zip | Cùng IP |
| 2. Xe/bất động sản | Năm, hãng, mẫu xe | Cùng IP |
| 3. Chọn phạm vi bảo hiểm | Hạn mức, mức khấu trừ | Cùng IP |
| 4. Giải CAPTCHA | Token | Cùng IP |
| 5. Hiển thị báo giá | — | Cùng IP |
Dùng phiên cố định nội bộ với TTL 10-15 phút — đủ hoàn tất 5 bước, đủ ngắn để không giữ session thừa.
Thu thập báo giá bảo hiểm ô tô từ nhiều carrier
Gửi từng bước biểu mẫu, giải reCAPTCHA v2 qua CaptchaAI, rồi so sánh phí và chọn mức thấp nhất:
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:[email protected]: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']}")
So sánh gói bảo hiểm y tế
Cổng bảo hiểm y tế bắt nhập nhân khẩu học trước; CAPTCHA xuất hiện ngay trước khi hiển thị gói:
def compare_health_plans(marketplace_url, demographics, sitekey):
"""Compare health insurance plans on marketplace sites."""
collector = InsuranceQuoteCollector(
proxy="http://user-session-xyz:[email protected]: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 []
Khắc phục sự cố thường gặp
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| Biểu mẫu báo giá bị reset giữa chừng | IP đổi giữa các bước | Dùng phiên cố định nội bộ |
| "Không thể cung cấp báo giá" | Xác thực dữ liệu thất bại | Kiểm tra lại các trường bắt buộc |
| CAPTCHA xuất hiện hai lần | Token đầu tiên đã hết hạn | Giải lại ngay lập tức |
| Phí hiển thị khác khi tra thủ công | Khác biệt cookie/session | Bắt đầu một phiên mới, sạch |
| Request bị chặn do rate limit | Gửi quá nhiều báo giá từ một IP | Giãn cách request, đổi IP giữa các carrier |
Câu hỏi thường gặp
Mỗi ngày thu thập được bao nhiêu báo giá bảo hiểm?
Thường 20-50 báo giá mỗi carrier mỗi ngày nếu giãn cách hợp lý; vượt ngưỡng này carrier siết rate limit và tăng tần suất CAPTCHA.
reCAPTCHA v3 trên biểu mẫu doanh nghiệp có khác reCAPTCHA v2 không?
Có phần khác. reCAPTCHA v3 chấm điểm hành vi, không hiện ô xác nhận — nhưng luồng gọi CaptchaAI giống hệt reCAPTCHA v2.
Nhiều carrier cùng lúc có cần gói CaptchaAI lớn không?
Tùy số carrier song song. Với 3-5 carrier như ví dụ trên, BASIC ($15/tháng, 5 thread) thường đủ; 20-30 carrier thì ADVANCE ($90/tháng, 50 thread) phù hợp hơn.
Có thể thử trên staging trước khi thu thập báo giá thật không?
Nên vậy — chạy collector trên URL staging của đội bạn trước khi trỏ sang trang thật.
Hướng dẫn liên quan
- Phiên cố định và phiên luân phiên
- Duy trì phiên trình duyệt
- Xác thực proxy với CaptchaAI
So sánh báo giá bảo hiểm ở quy mô lớn — lấy API key CaptchaAI và tự động hóa việc thu thập.