Каждый тип CAPTCHA имеет разное время решения. Использование единого тайм-аута для всех типов либо приводит к потере времени для быстрых CAPTCHA, либо к преждевременному истечению времени для более медленных. Настройте тайм-ауты для каждого типа для оптимальной производительности.
Рекомендуемые таймауты по типам
| Тип капчи | Среднее время решения | Начальное ожидание | Интервал опроса | Макс. тайм-аут |
|---|---|---|---|---|
| Изображение/OCR | 2–5 с. | 3 с | 3 с | 30 с |
| reCAPTCHA v2 | 10–20 секунд | 10 с | 5 с | 90-е |
| reCAPTCHA v3 | 5–15 с. | 5 с | 5 с | 60-е годы |
| reCAPTCHA Предприятие | 10–25 сек. | 10 с | 5 с | 120 с |
| Невидимая reCAPTCHA | 10–20 секунд | 10 с | 5 с | 90-е |
| Cloudflare Turnstile | 3-10 с | 3 с | 3 с | 45 с |
| страница Cloudflare-защиты в staging | 10–30 секунд | 10 с | 5 с | 120 с |
| GeeTest v3 | 5–15 с. | 5 с | 5 с | 60-е годы |
| БЛС | 3-10 с | 3 с | 5 с | 45 с |
Решатель с учетом типов
import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://ocr.captchaai.com"
# Per-type timeout configuration
TIMEOUT_CONFIG = {
"base64": {
"initial_wait": 3,
"poll_interval": 3,
"max_timeout": 30,
},
"userrecaptcha": {
"initial_wait": 10,
"poll_interval": 5,
"max_timeout": 90,
},
"userrecaptcha_v3": {
"initial_wait": 5,
"poll_interval": 5,
"max_timeout": 60,
},
"turnstile": {
"initial_wait": 3,
"poll_interval": 3,
"max_timeout": 45,
},
"turnstile": {
"initial_wait": 10,
"poll_interval": 5,
"max_timeout": 120,
},
"geetest": {
"initial_wait": 5,
"poll_interval": 5,
"max_timeout": 60,
},
"bls": {
"initial_wait": 3,
"poll_interval": 5,
"max_timeout": 45,
},
"default": {
"initial_wait": 10,
"poll_interval": 5,
"max_timeout": 120,
},
}
def get_config_key(method, **params):
"""Determine config key from method and parameters."""
if method == "userrecaptcha" and params.get("version") == "v3":
return "userrecaptcha_v3"
return method
def solve(method, **params):
"""Solve CAPTCHA with type-appropriate timeouts."""
config_key = get_config_key(method, **params)
config = TIMEOUT_CONFIG.get(config_key, TIMEOUT_CONFIG["default"])
# Submit task
data = {"key": API_KEY, "method": method, "json": 1}
data.update(params)
resp = requests.post(f"{BASE_URL}/in.php", data=data, timeout=30)
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit error: {result.get('request')}")
task_id = result["request"]
# Wait before first poll
time.sleep(config["initial_wait"])
# Poll with type-specific interval and timeout
start = time.time()
while time.time() - start < config["max_timeout"]:
resp = requests.get(f"{BASE_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": 1,
}, timeout=15)
data = resp.json()
if data["request"] != "CAPCHA_NOT_READY":
elapsed = time.time() - start + config["initial_wait"]
print(f"Solved {method} in {elapsed:.1f}s")
return data["request"]
time.sleep(config["poll_interval"])
raise TimeoutError(
f"{method} timeout after {config['max_timeout']}s"
)
# Usage — each type uses optimal timeouts automatically
# Image (fast: 3s wait, 3s poll, 30s max)
token = solve("base64", body=base64_image)
# reCAPTCHA v2 (medium: 10s wait, 5s poll, 90s max)
token = solve("userrecaptcha", googlekey="KEY", pageurl="https://example.com")
# Turnstile (fast: 3s wait, 3s poll, 45s max)
token = solve("turnstile", sitekey="KEY", pageurl="https://example.com")
Динамическая регулировка тайм-аута
Отрегулируйте таймауты на основе наблюдаемого времени решения:
import statistics
class AdaptiveTimeoutSolver:
"""Adjusts timeouts based on historical solve times."""
def __init__(self, api_key):
self.api_key = api_key
self.base = "https://ocr.captchaai.com"
self.history = {} # method -> [solve_times]
def solve(self, method, **params):
config = self._get_config(method)
# Submit
data = {"key": self.api_key, "method": method, "json": 1}
data.update(params)
resp = requests.post(f"{self.base}/in.php", data=data, timeout=30)
task_id = resp.json()["request"]
time.sleep(config["initial_wait"])
start = time.time()
# Poll with adaptive timeout
while time.time() - start < config["max_timeout"]:
resp = requests.get(f"{self.base}/res.php", params={
"key": self.api_key, "action": "get",
"id": task_id, "json": 1,
})
data = resp.json()
if data["request"] != "CAPCHA_NOT_READY":
elapsed = time.time() - start + config["initial_wait"]
self._record(method, elapsed)
return data["request"]
time.sleep(config["poll_interval"])
raise TimeoutError(f"Timeout after {config['max_timeout']}s")
def _get_config(self, method):
"""Get timeout config, adjusted by history."""
base = TIMEOUT_CONFIG.get(method, TIMEOUT_CONFIG["default"])
# If we have history, adjust max_timeout
times = self.history.get(method, [])
if len(times) >= 5:
p95 = sorted(times)[int(len(times) * 0.95)]
adjusted_timeout = max(p95 * 2, base["max_timeout"])
return {**base, "max_timeout": adjusted_timeout}
return base
def _record(self, method, elapsed):
if method not in self.history:
self.history[method] = []
self.history[method].append(elapsed)
# Keep last 100 entries
if len(self.history[method]) > 100:
self.history[method] = self.history[method][-100:]
def get_stats(self, method):
times = self.history.get(method, [])
if not times:
return None
return {
"count": len(times),
"mean": statistics.mean(times),
"median": statistics.median(times),
"p95": sorted(times)[int(len(times) * 0.95)],
"max": max(times),
}
# Usage
solver = AdaptiveTimeoutSolver("YOUR_API_KEY")
token = solver.solve("turnstile", sitekey="KEY", pageurl="https://example.com")
print(solver.get_stats("turnstile"))
Тайм-аут отправки и тайм-аут опроса
Два разных таймаута для настройки:
Submit timeout: How long to wait for the API to accept your task
→ Set to 30s (network issues only)
Poll timeout: How long to wait for the solve result
→ Varies by CAPTCHA type (30s to 120s)
# Submit timeout (fixed, short)
resp = requests.post(
f"{BASE_URL}/in.php", data=data,
timeout=30, # 30s is plenty for submission
)
# Poll timeout (varies by type)
resp = requests.get(
f"{BASE_URL}/res.php", params=params,
timeout=15, # 15s per individual poll request
)
# Overall polling loop timeout: 30-120s depending on type
Поиск неисправностей
| Проблема | Причина | Исправить |
|---|---|---|
| Тайм-аут CAPTCHA для изображений составляет 120 с. | Тайм-аут слишком длинный, трата времени | Уменьшите до 30 секунд для изображений. |
| reCAPTCHA v2 истекло время ожидания | Максимальный тайм-аут слишком мал | Используйте минимум 90 секунд для reCAPTCHA v2. |
| Первый опрос всегда возвращает «не готов» | Первоначальное ожидание слишком короткое | Увеличение начального ожидания для таблицы типов |
| Чрезмерное количество запросов на опрос | Интервал опроса слишком короткий | Используйте 5 секунд для типов токенов, 3 секунды для изображений. |
Часто задаваемые вопросы
Почему бы не использовать один и тот же таймаут для всего?
Тайм-аут 120 секунд для графических CAPTCHA (которые решаются за 3 секунды) приводит к потере 117 секунд при сбоях. Тайм-аут 30 секунд для reCAPTCHA Enterprise может истечь при действительных решениях. Таймауты для каждого типа оптимизируют оба случая.
Что произойдет, если я установлю слишком маленькое время ожидания?
Вы получите ложные ошибки тайм-аута. Задача может быть выполнена на стороне CaptchaAI, но вы не получите результата. Установите таймауты как минимум в 2 раза превышающие среднее время решения.
Стоит ли увеличивать тайм-ауты в часы пик?
Вообще нет. Решение CaptchaAI на основе искусственного интеллекта обеспечивает постоянную скорость. Если вы видите увеличение времени решения, сначала проверьте задержку сети.
Связанные руководства
- Ограничение скорости и 429 ответов
- Повторить реализацию логики
Оптимизируйте каждую миллисекунду —попробуй CaptchaAIс настраиваемыми таймаутами.