政府门户的验证码能用 API 自动处理吗?能,但要先分清类型。
BLS 签证预约系统、法院和车管所常用的 reCAPTCHA v2、许可证和税务门户常见的图片验证码,处理逻辑并不相同。典型使用者是 QA 团队、公民科技开发者,以及批量查询 BLS 签证中心可约时段的旅行社。下面按门户类别拆解常见类型,附可直接改造的 Python 示例。
政府网站验证码类型速查
- 签证 / 移民(BLS 签证中心、美国移民局):BLS、reCAPTCHA v2 —— 预约申请
- 车管所(各州车管所网站):reCAPTCHA v2、图片验证码 —— 登记续期
- 法庭记录(PACER、州法院):reCAPTCHA v2 —— 案件查询
- 许可证 / 执照(市级许可证门户):图片验证码 —— 申请备案
- 税务门户(IRS、州税务网站):reCAPTCHA v2 —— 状态查询
- 公共记录(县级档案系统):图片验证码、reCAPTCHA —— 产权查询
BLS 签证预约验证码自动识别
使用场景
BLS 门户用自己的验证码系统,这里的 BLS 指签证预约机构,非统计部门。
合规提醒: BLS 等海外签证测试仅限已获授权账号,数据处理符合 PIPL 基本要求。
代码示例
用 method=bls 参数直接对接,识别通常在 1 秒内完成,成功率高:
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"),
}
法庭记录查询自动化(reCAPTCHA v2)
使用场景
大多数法院系统用标准 reCAPTCHA v2 保护查询表单。
代码示例
提取 sitekey/pageurl 后把 token 提交到搜索接口:
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
许可证与执照门户的图片验证码识别
使用场景
很多市县许可证门户还在用最基础的图片验证码。
代码示例
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")
公共记录批量查询与验证码处理
使用场景
批量查询产权记录时,按批次识别能明显降低耗时,无需每次都重新识别。
代码示例
下面复用前面定义的 solve_recaptcha:
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
政府门户会话管理与超时应对
政府门户的会话超时往往比想象中更短:
- 签证预约门户:超时 5–10 分钟 —— 尽快走完流程
- 车管所网站:超时 15 分钟 —— 中途刷新 cookie
- 法庭记录系统:超时 20–30 分钟 —— 分批执行查询
- 税务门户:超时 10–15 分钟 —— 持久 QA 会话保持同一 IP
- 许可证申请:超时 30 分钟 —— 每步保存进度
自动化过程中的常见故障与处理
遇到下面情况,大概率是会话或时序问题:
- 验证码图片加载不出来 —— 会话 cookie 过期,重新开会话。
- 提示"会话已过期" —— 识别耗时太长,提前识别或换更快类型。
- 验证码答案不对 —— 图片本身失真,通过 API 反馈问题图片。
- 门户拦截自动化请求 —— IP / UA 特征被识别,换自有服务器基础设施。
- 提交后 token 校验失败 —— 服务器端 token 过期,识别完立刻提交。
常见问题
自动化政府门户网站合法吗?
自动化自己的表单和数据查询通常允许,但需先确认服务条款。
政府网站最常见的是哪种验证码?
图片验证码和 reCAPTCHA v2 最常见,识别难度低于电商平台。
测试 BLS 等海外签证系统要注意合规问题吗?
是,仅使用已获授权账号,数据处理符合 PIPL 要求。
政府门户会不会因为自动化请求而封锁 IP?
会,建议用自有服务器基础设施加真实 UA。
可以先用免费额度测试自动化流程吗?
可以,先跑通识别流程再升级到 BASIC($15/月,5 线程)等套餐。