API Tutorials

Оптимизация задержки API CaptchaAI: более быстрое решение

Если парсер простаивает по 20–30 секунд между отправкой CAPTCHA и получением токена, виноват обычно не решатель, а то, как вы его вызываете.

Задержка одного решения складывается из четырёх частей:

  • отправка запроса на сервер CaptchaAI;
  • ожидание задачи в очереди;
  • работа самого решателя;
  • получение результата опросом или через callback.

Повлиять вы можете на всё, кроме времени самого решения, — этому и посвящена статья.


Ориентир: сколько задержки нормально для каждого типа CAPTCHA

Прежде чем оптимизировать, полезно знать, к чему стремиться: официальный потолок SLA и результат, который реально получают команды после приёмов из этой статьи.

Тип CAPTCHA Потолок SLA Достижимый результат
Image/OCR <0,5 с 0,2–0,4 с
reCAPTCHA v2 <60 с 10–20 с
reCAPTCHA v3 <4 с 1–3 с
Cloudflare Turnstile <10 с 4–8 с
GeeTest v3 <12 с 6–10 с

Часть задержки — не на стороне CaptchaAI, а в сети: при хостинге в Европе RTT до ocr.captchaai.com обычно ниже, чем при более длинном маршруте (мобильный канал, хостинг в Центральной Азии). Перед тюнингом кода измерьте фактический RTT — так вы поймёте, сколько съедает сеть, а сколько реально даёт оптимизация.


1. Настройте адаптивный опрос вместо фиксированного интервала

Опрос раз в 5 секунд по умолчанию часто тратит время впустую: решение готово, а вы всё равно ждёте до следующего цикла.

Адаптивный опрос устраняет это — начинайте агрессивно, затем снижайте частоту:

Python

import time
import requests

API_KEY = "YOUR_API_KEY"
RESULT_URL = "https://ocr.captchaai.com/res.php"

def adaptive_poll(task_id, timeout=120):
    """Start polling at 3s, increase to 5s after 4 polls."""
    start = time.time()
    interval = 3  # start aggressive
    polls = 0

    while time.time() - start < timeout:
        time.sleep(interval)
        polls += 1

        resp = requests.get(RESULT_URL, params={
            "key": API_KEY, "action": "get",
            "id": task_id, "json": "1"
        }).json()

        if resp["status"] == 1:
            elapsed = time.time() - start
            print(f"Solved in {elapsed:.1f}s ({polls} polls)")
            return resp["request"]

        if resp["request"] != "CAPCHA_NOT_READY":
            raise Exception(resp["request"])

        # Back off after initial fast polls
        if polls >= 4:
            interval = 5

    raise TimeoutError(f"Task {task_id} timed out")

Та же логика на JavaScript:

JavaScript

async function adaptivePoll(taskId, apiKey, timeout = 120000) {
  const start = Date.now();
  let interval = 3000;
  let polls = 0;

  while (Date.now() - start < timeout) {
    await new Promise(r => setTimeout(r, interval));
    polls++;

    const resp = await fetch(
      `https://ocr.captchaai.com/res.php?key=${apiKey}&action=get&id=${taskId}&json=1`
    );
    const data = await resp.json();

    if (data.status === 1) {
      console.log(`Solved in ${((Date.now() - start) / 1000).toFixed(1)}s (${polls} polls)`);
      return data.request;
    }
    if (data.request !== 'CAPCHA_NOT_READY') {
      throw new Error(data.request);
    }

    if (polls >= 4) interval = 5000;
  }
  throw new Error(`Task ${taskId} timed out`);
}

В среднем это экономит 1–4 секунды по сравнению с фиксированным пятисекундным интервалом. Пара нюансов при подборе параметров:

  • для reCAPTCHA v2 стартовый интервал 3 с почти всегда оправдан — решение редко готово раньше;
  • для быстрых типов вроде Image/OCR выигрыш от агрессивного старта скромнее (см. FAQ ниже).

2. Переиспользуйте HTTP-соединения (пул соединений)

Каждое новое TCP/TLS-соединение — лишний round-trip ещё до самого запроса.

Переиспользуйте соединение вместо того, чтобы открывать новое на каждый опрос:

Python

session = requests.Session()
# Use session.get() and session.post() instead of requests.get/post
# The session reuses TCP connections automatically

Аналог на Node.js:

JavaScript (Node.js)

const { Agent } = require('http');
const axios = require('axios');

const client = axios.create({
  httpAgent: new Agent({ keepAlive: true, maxSockets: 10 }),
  timeout: 10000,
});
// Use client.get() and client.post() for all API calls

Экономия обычно 50–100 мс на запрос за счёт пропуска повторных TCP/TLS-рукопожатий. Проверить эффект просто:

  • сравните P95 из раздела 7 до и после перехода на Session/Agent;
  • если разница почти незаметна, скорее всего сессия уже переиспользуется где-то в коде.

3. Отправляйте CAPTCHA заранее (prefetch)

Не ждите, когда токен понадобится, — отправляйте задачу заранее. Пока парсер обрабатывает страницу N, отправьте CAPTCHA для N+1:

from concurrent.futures import ThreadPoolExecutor

SUBMIT_URL = "https://ocr.captchaai.com/in.php"

def prefetch_submit(sitekey, page_url):
    resp = session.post(SUBMIT_URL, data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": page_url,
        "json": "1",
    })
    data = resp.json()
    if data["status"] == 1:
        return data["request"]
    raise Exception(data["request"])

# Submit next page's CAPTCHA while processing current page
with ThreadPoolExecutor(max_workers=2) as pool:
    # Submit CAPTCHA for page 2 while processing page 1
    future_task = pool.submit(prefetch_submit, "6Le-SITEKEY", "https://example.com/page/2")

    # Process page 1...
    process_page(current_data)

    # Now get the pre-submitted task ID and poll
    task_id = future_task.result()
    token = adaptive_poll(task_id)

Так решение перекрывается с обработкой страницы, и суммарное ожидание в пайплайне уходит почти в ноль.

Ограничение одно: не отправляйте задачи слишком далеко вперёд. Токен CaptchaAI не бессрочный, и prefetch на 10+ страниц вперёд рискует истечь до использования.


4. Выбирайте более быстрый метод API, если он есть

Для части сценариев у CaptchaAI есть альтернатива быстрее опроса:

Сценарий Медленный вариант Более быстрая альтернатива
reCAPTCHA v2 с настроенным callback userrecaptcha + опрос userrecaptcha с pingback (URL обратного вызова)
Текстовая CAPTCHA-картинка base64 в высоком разрешении base64 с numeric=1, если ответ — только цифры

5. Не подключайте прокси без необходимости

Маршрутизация через прокси добавляет задержку. Прокси нужен не всегда:

  • целевой сайт требует запросов с определённого IP или гео — прокси обязателен;
  • сайт не проверяет источник запроса — быстрее отправлять напрямую.

Передавайте параметры прокси только в первом случае:

# Without proxy — faster for most use cases
data = {
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "json": "1",
}

# With proxy — only when required
data["proxy"] = "user:[email protected]:8080"
data["proxytype"] = "HTTP"

Тестируйте оба варианта на реальном трафике, а не только локально: разница в задержке между «с прокси» и «без прокси» может отличаться от прогноза из-за состояния конкретного прокси-пула.


6. Заменяйте опрос колбэком pingback

Параметр pingback убирает цикл опроса полностью:

resp = session.post(SUBMIT_URL, data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "json": "1",
    "pingback": "https://your-server.com/captcha-callback",
})

CaptchaAI сам отправит результат на указанный URL — опрашивать res.php не придётся.

По нашим внутренним замерам pingback стабильно быстрее регулярного опроса за счёт меньшего числа HTTP-запросов.


7. Измеряйте эффект оптимизаций

Не полагайтесь на ощущения — снимайте цифры до и после:

import statistics

def benchmark(solve_func, iterations=20):
    times = []
    for i in range(iterations):
        start = time.time()
        try:
            solve_func()
            times.append(time.time() - start)
        except Exception:
            pass

    if times:
        print(f"Samples: {len(times)}/{iterations}")
        print(f"Mean:    {statistics.mean(times):.1f}s")
        print(f"Median:  {statistics.median(times):.1f}s")
        print(f"P95:     {sorted(times)[int(len(times)*0.95)]:.1f}s")
        print(f"Min:     {min(times):.1f}s")
        print(f"Max:     {max(times):.1f}s")

Частые проблемы при оптимизации задержки

  • Задержка опроса не изменилась. Скорее всего код всё ещё использует requests.get() без сессии — перейдите на session.get().
  • Токены prefetch истекают до использования. Обработка страницы занимает слишком много времени — сократите окно prefetch или отправляйте задачу ближе к моменту использования.
  • Callback URL не получает данные. Сервер недоступен со стороны CaptchaAI — убедитесь, что URL публичный, и проверьте правила файрвола.
  • Более частый опрос упирается в лимит запросов. Опрос слишком агрессивный (< 2 с) — держите минимальный интервал в 3 секунды.

Вопросы, которые обычно возникают

Коротко отвечаем на то, что чаще всего спрашивают при внедрении этих приёмов.

Что оптимизировать в первую очередь, если время на доработку ограничено?

Prefetch: он перекрывает решение со временем обработки страницы и сильнее всего снижает воспринимаемую задержку в последовательных пайплайнах.

Даёт ли адаптивный опрос ощутимый выигрыш для Image/OCR?

Не сильно. Image/OCR решается за 0,2–0,4 секунды, и первый опрос на 3-й секунде почти всегда застаёт результат готовым. Заметнее — на reCAPTCHA v2 (10–20 секунд).

Почему подключение прокси иногда добавляет секунды к решению?

Прокси — лишний сетевой узел, часто более медленный. Подключайте его только там, где сайт требует запросов с определённого IP, — в остальных случаях идите напрямую.

Как проверить, сколько задержки добавляет сеть, а не решатель?

Замерьте RTT до https://ocr.captchaai.com и сравните с показаниями benchmark() из раздела 7. Разница — то, что реально можно сократить кодом.

Сколько потоков нужно, чтобы задержка одной задачи не тормозила весь пайплайн?

Это вопрос пропускной способности, а не задержки одной задачи.

CaptchaAI тарифицирует по числу одновременных потоков, а не по числу решений. На плане BASIC ($15/мес, 5 потоков) вы решаете до 5 задач параллельно — если нужно больше, увеличивайте план.


Сократите задержку решения CAPTCHA с CaptchaAI

Все приёмы из статьи работают с одним и тем же API-ключом — менять инфраструктуру не нужно.

Получите ключ на captchaai.com и подключите адаптивный опрос и pingback.


Похожие руководства

Если задержка — не единственное, что нужно оптимизировать, посмотрите смежные темы:

Комментарии для этой статьи отключены.