Đội QA đặt lịch hẹn visa qua BLS hàng trăm lần để test luồng đăng ký, dev công nghệ dân sự tra cứu hồ sơ tòa án theo lô, outsourcing xác minh biểu mẫu cấp phép — CAPTCHA chặn cả ba luồng ngay từ bước đăng nhập. CaptchaAI xử lý bước đó qua API: gửi ảnh hoặc sitekey, nhận token, điền lại vào form. Bài này đi thẳng vào từng loại cổng — BLS, tòa án, DMV, cấp phép — kèm code Python chạy được ngay.
Các loại CAPTCHA trên cổng thông tin chính phủ
CAPTCHA trên các trang chính phủ bảo vệ biểu mẫu, đặt lịch hẹn và cổng tra cứu hồ sơ — kể cả các cổng dạng Cổng Dịch vụ công Quốc gia tại Việt Nam. Ba đặc điểm chung:
- Công nghệ thường cũ hơn khu vực thương mại — nhiều nơi vẫn chỉ dùng reCAPTCHA v2 hoặc CAPTCHA ảnh.
- Phiên đăng nhập ngắn, cần giải và submit ngay.
- Một số hệ thống (BLS, DMV) dùng cơ chế CAPTCHA riêng, không theo chuẩn Google.
| Danh mục cổng thông tin | CAPTCHA phổ biến | Trang web mẫu | Trường hợp sử dụng |
|---|---|---|---|
| Thị thực/nhập cư | BLS, reCAPTCHA v2 | Cổng thông tin BLS, USCIS | Đặt lịch hẹn |
| DMV/xe cơ giới | reCAPTCHA v2, hình ảnh | Các trang web DMV của tiểu bang | Gia hạn đăng ký |
| Hồ sơ tòa án | reCAPTCHA v2 | PACER, tòa án tiểu bang | Tra cứu trường hợp |
| Giấy phép/cấp phép | CAPTCHA hình ảnh | Cổng thông tin giấy phép thành phố | Nộp hồ sơ |
| Cổng thông tin thuế | reCAPTCHA v2 | IRS, trang web thuế tiểu bang | Kiểm tra tình trạng nộp hồ sơ |
| Hồ sơ công cộng | CAPTCHA hình ảnh, reCAPTCHA | Hồ sơ quận | Tra cứu Property/deed |
Tự động hóa đặt lịch hẹn visa qua cổng BLS
Cổng BLS dùng hệ thống CAPTCHA riêng, không phải reCAPTCHA chuẩn. CaptchaAI giải BLS CAPTCHA với tỷ lệ thành công cao, dưới 1 giây:
import requests
import time
import base64
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_bls_captcha(captcha_image_url, session):
"""Solve BLS-specific CAPTCHA."""
# Download CAPTCHA image
img_resp = session.get(captcha_image_url)
img_b64 = base64.b64encode(img_resp.content).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(30):
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("BLS CAPTCHA timeout")
class BLSAppointmentBooker:
def __init__(self):
self.session = requests.Session()
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 login(self, portal_url, email, password):
"""Login to BLS portal with CAPTCHA."""
resp = self.session.get(portal_url)
# Extract CAPTCHA image URL from page
import re
match = re.search(r'src="(/captcha[^"]+)"', resp.text)
if match:
captcha_url = portal_url.rstrip("/") + match.group(1)
captcha_text = solve_bls_captcha(captcha_url, self.session)
else:
captcha_text = ""
login_resp = self.session.post(portal_url, data={
"email": email,
"password": password,
"captcha": captcha_text,
})
return login_resp.status_code == 200
def check_appointment_slots(self, slots_url):
"""Check available appointment slots."""
resp = self.session.get(slots_url)
if resp.status_code == 200:
return resp.json().get("available_slots", [])
return []
def book_slot(self, booking_url, slot_id, applicant_data):
"""Book an appointment slot, handling any CAPTCHA."""
resp = self.session.get(booking_url)
# Check for CAPTCHA on booking page
import re
match = re.search(r'src="(/captcha[^"]+)"', resp.text)
if match:
captcha_url = booking_url.rstrip("/") + match.group(1)
captcha_text = solve_bls_captcha(captcha_url, self.session)
else:
captcha_text = ""
resp = self.session.post(booking_url, data={
"slot_id": slot_id,
"captcha": captcha_text,
**applicant_data,
})
return {
"success": resp.status_code == 200,
"confirmation": resp.json().get("confirmation_number"),
}
Nhiều đội QA outsourcing ở TP.HCM và Hà Nội dùng đúng luồng này để test hành trình đặt lịch visa, thay vì bấm tay từng CAPTCHA mỗi lần chạy regression.
Tra cứu hồ sơ tòa án bằng reCAPTCHA v2
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")
class CourtRecordSearcher:
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 search_cases(self, court_url, search_params, sitekey):
"""Search court records with reCAPTCHA handling."""
# Load search page
self.session.get(court_url)
# Solve CAPTCHA
token = solve_recaptcha(sitekey, court_url)
# Submit search with token
resp = self.session.post(court_url, data={
**search_params,
"g-recaptcha-response": token,
})
if resp.status_code == 200:
return self._parse_results(resp.text)
return []
def _parse_results(self, html):
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
cases = []
for row in soup.select("table.results tr")[1:]:
cols = row.select("td")
if len(cols) >= 4:
cases.append({
"case_number": cols[0].get_text(strip=True),
"parties": cols[1].get_text(strip=True),
"date": cols[2].get_text(strip=True),
"status": cols[3].get_text(strip=True),
})
return cases
Cổng tòa án Mỹ như PACER dùng reCAPTCHA v2 chuẩn — lấy sitekey từ HTML, gửi kèm pageurl tới in.php, polling res.php đến khi có token, rồi đặt vào field g-recaptcha-response.
Giải CAPTCHA hình ảnh trên cổng cấp phép
Nhiều cổng thành phố và quận dùng CAPTCHA hình ảnh đơn giản, giải dưới 0,5 giây:
def solve_image_captcha(image_url, session):
"""Solve image-based CAPTCHA common on local government sites."""
img = session.get(image_url)
img_b64 = base64.b64encode(img.content).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("Image CAPTCHA timeout")
Tra cứu hàng loạt hồ sơ công (bất động sản, đất đai)
import csv
def batch_property_lookup(addresses, portal_url, sitekey, output_file):
"""Look up multiple property records, solving CAPTCHA per batch."""
session = requests.Session()
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",
})
results = []
for i, address in enumerate(addresses):
try:
# Solve CAPTCHA every 5th request (or when required)
if i % 5 == 0:
token = solve_recaptcha(sitekey, portal_url)
resp = session.post(portal_url, data={
"address": address,
"g-recaptcha-response": token,
})
if resp.status_code == 200:
results.append({
"address": address,
"data": resp.json(),
})
time.sleep(3) # Be respectful
except Exception as e:
results.append({"address": address, "error": str(e)})
# Save results
with open(output_file, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["address", "data", "error"])
writer.writeheader()
writer.writerows(results)
return results
Chỉ giải lại CAPTCHA sau mỗi 5 request — hầu hết cổng hồ sơ công chỉ yêu cầu token mới theo phiên; time.sleep(3) giúp tránh quá tải server.
Khắc phục sự cố thường gặp
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| Hình ảnh CAPTCHA không tải | Cookie phiên hết hạn | Bắt đầu phiên mới |
| "Phiên đã hết hạn" khi gửi biểu mẫu | Giải CAPTCHA quá lâu | Giải trước hoặc dùng luồng nhanh hơn |
| CAPTCHA trả sai đáp án | Ảnh bị biến dạng | Báo lỗi ảnh qua API |
| Cổng chặn tự động hóa | Phát hiện qua IP/User-Agent | Đa dạng nguồn request + UA thật |
| Lỗi xác thực form sau CAPTCHA | Token server hết hạn | Giải ngay trước khi submit |
Mẹo quản lý phiên khi tự động hóa cổng thông tin chính phủ
Cổng chính phủ thường có phiên ngắn hơn cổng thương mại điện tử:
| Loại cổng thông tin | Thời gian chờ của phiên | Khuyến nghị |
|---|---|---|
| Cổng thị thực | 5-10 phút | Hoàn thành luồng nhanh |
| Trang web DMV | 15 phút | Làm mới cookie giữa chừng |
| Hồ sơ tòa án | 20-30 phút | Gom tìm kiếm thành từng lô |
| Cổng thuế | 10-15 phút | Giữ phiên cố định nội bộ |
| Cổng cấp phép | 30 phút | Lưu tiến độ mỗi bước |
Câu hỏi thường gặp
Giải một lần BLS CAPTCHA mất bao lâu và tốn bao nhiêu?
Dưới 1 giây. Chi phí tính theo thread chứ không theo lần giải — gói BASIC ($15/tháng, 5 thread) đủ cho hầu hết đội QA chạy vài trăm lượt đặt lịch mỗi tháng.
CaptchaAI có giải được CAPTCHA trên Cổng Dịch vụ công Quốc gia không?
Còn tùy loại CAPTCHA cổng đó dùng — CaptchaAI hỗ trợ reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest v3 và CAPTCHA hình ảnh/OCR qua API in.php/res.php.
Tự động hóa cổng thông tin chính phủ có hợp pháp không?
Tự động hóa biểu mẫu và tra cứu dữ liệu của chính bạn (hoặc khách hàng ủy quyền) thường được cho phép — luôn kiểm tra điều khoản dịch vụ từng cổng trước khi chạy hàng loạt.
Cổng BLS thường dùng loại CAPTCHA nào?
Hệ thống CAPTCHA riêng, không phải reCAPTCHA chuẩn của Google. CaptchaAI giải trực tiếp bằng method=bls, hoặc method=base64 khi giải theo ảnh chụp.
Làm sao xử lý phiên bị hết hạn khi điền form nhiều bước?
Giữ cùng một phiên cố định nội bộ suốt quá trình điền form. Nhiều cổng chính phủ đối chiếu tính nhất quán của phiên giữa các trang biểu mẫu.