Quay Lại BlogMẹo
Xử Lý Lỗi CAPTCHA API: Phương Pháp Tốt Nhất Cho Production
Xây dựng tích hợp bền vững với xử lý timeout đúng cách, logic retry, circuit breakers và mẫu graceful degradation.
Đội ngũ reGOTCHA12 tháng 12, 20256 phút đọc
Tại Sao Xử Lý Lỗi Quan Trọng
Giải CAPTCHA liên quan đến API bên ngoài, request mạng và các thao tác nhạy cảm về thời gian. Xử lý lỗi mạnh mẽ ngăn ngừa lỗi lan truyền và lãng phí tài nguyên.
Các Loại Lỗi Phổ Biến
1. Lỗi Mạng
example.py
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10)
)
async def create_task(client, params):
try:
response = await client.post("/createTask", json=params)
response.raise_for_status()
return response.json()
except httpx.TimeoutException:
raise # Để tenacity retry
except httpx.HTTPStatusError as e:
if e.response.status_code >= 500:
raise # Retry lỗi server
raise e # Không retry lỗi client2. Lỗi API
example.py
class CaptchaAPIError(Exception):
def __init__(self, error_id: int, description: str):
self.error_id = error_id
self.description = description
super().__init__(f"Lỗi {error_id}: {description}")
ERROR_CODES = {
1: "API key không hợp lệ",
2: "Không đủ số dư",
3: "Không tìm thấy task",
10: "Site key không hợp lệ",
12: "Task timeout",
}
def handle_api_response(data: dict):
if error_id := data.get("errorId"):
desc = ERROR_CODES.get(error_id, data.get("errorDescription", "Không rõ"))
raise CaptchaAPIError(error_id, desc)3. Xử Lý Timeout
example.py
import asyncio
async def solve_with_timeout(solver, params, timeout=120):
try:
return await asyncio.wait_for(
solver.solve(**params),
timeout=timeout
)
except asyncio.TimeoutError:
# Log cho metrics
logger.warning(f"Giải CAPTCHA timeout sau {timeout}s")
raise
# Với fallback
async def solve_with_fallback(solvers, params):
for solver in solvers:
try:
return await solve_with_timeout(solver, params)
except Exception as e:
logger.warning(f"Solver {solver.name} thất bại: {e}")
continue
raise Exception("Tất cả solver thất bại")Mẫu Circuit Breaker
example.py
from datetime import datetime, timedelta
from enum import Enum
class CircuitState(Enum):
CLOSED = "closed"
OPEN = "open"
HALF_OPEN = "half_open"
class CircuitBreaker:
def __init__(
self,
failure_threshold: int = 5,
recovery_timeout: int = 60,
half_open_max: int = 3
):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.half_open_max = half_open_max
self.state = CircuitState.CLOSED
self.failures = 0
self.last_failure_time = None
self.half_open_calls = 0
async def call(self, func, *args, **kwargs):
if self.state == CircuitState.OPEN:
if self._should_try_reset():
self.state = CircuitState.HALF_OPEN
self.half_open_calls = 0
else:
raise Exception("Circuit breaker đang mở")
try:
result = await func(*args, **kwargs)
self._on_success()
return result
except Exception as e:
self._on_failure()
raise
def _should_try_reset(self):
return (
self.last_failure_time and
datetime.now() - self.last_failure_time >
timedelta(seconds=self.recovery_timeout)
)
def _on_success(self):
if self.state == CircuitState.HALF_OPEN:
self.half_open_calls += 1
if self.half_open_calls >= self.half_open_max:
self.state = CircuitState.CLOSED
self.failures = 0
def _on_failure(self):
self.failures += 1
self.last_failure_time = datetime.now()
if self.failures >= self.failure_threshold:
self.state = CircuitState.OPENGraceful Degradation
example.py
class CaptchaSolverWithFallback:
def __init__(self, primary_solver, fallback_strategy):
self.primary = primary_solver
self.fallback = fallback_strategy
self.circuit = CircuitBreaker()
async def solve(self, **params):
try:
return await self.circuit.call(
self.primary.solve,
**params
)
except Exception as e:
logger.warning(f"Solver chính thất bại: {e}")
return await self.fallback(**params)
# Chiến lược fallback
async def queue_for_manual_review(**params):
"""Đưa task vào queue xử lý thủ công"""
await task_queue.push({
"type": "captcha_manual",
"params": params,
"created_at": datetime.now()
})
return None
async def skip_captcha_action(**params):
"""Bỏ qua hành động yêu cầu CAPTCHA"""
logger.info(f"Bỏ qua hành động được bảo vệ CAPTCHA: {params}")
return NoneGiám Sát & Cảnh Báo
example.py
from dataclasses import dataclass
from collections import deque
@dataclass
class SolverMetrics:
total_attempts: int = 0
successes: int = 0
failures: int = 0
timeouts: int = 0
avg_solve_time: float = 0.0
recent_errors: deque = None
def __post_init__(self):
self.recent_errors = deque(maxlen=100)
@property
def success_rate(self):
if self.total_attempts == 0:
return 0.0
return self.successes / self.total_attempts * 100
def should_alert(self):
# Cảnh báo nếu tỷ lệ thành công dưới 80%
return self.success_rate < 80 and self.total_attempts > 10
# Sử dụng
metrics = SolverMetrics()
async def solve_with_metrics(solver, params):
start = time.time()
metrics.total_attempts += 1
try:
result = await solver.solve(**params)
metrics.successes += 1
metrics.avg_solve_time = (
metrics.avg_solve_time * 0.9 +
(time.time() - start) * 0.1
)
return result
except asyncio.TimeoutError:
metrics.timeouts += 1
raise
except Exception as e:
metrics.failures += 1
metrics.recent_errors.append(str(e))
raiseMẹo Chuyên Nghiệp: Triển khai health check xác minh pipeline giải CAPTCHA hoạt động trước khi cần trong quy trình production.
APIXử lý lỗiProductionPhương pháp tốt
Sẵn sàng giải quyết CAPTCHA theo quy mô?
Bắt đầu với 50 tín dụng miễn phí. Không cần thẻ tín dụng.