Use Cases

Автоматизация обработки CAPTCHA ботом с помощью CaptchaAI

Бот упирается в CAPTCHA ровно там, где автоматизация должна была работать без вас. API CaptchaAI решает CAPTCHA программно и отдаёт боту готовый токен, так что скрипт продолжает без паузы на человека.

Что нужно, чтобы бот сам проходил CAPTCHA:

  • API-ключ CaptchaAI и метод под конкретный тип CAPTCHA (userrecaptcha, turnstile, base64, cloudflare_challenge).
  • Опрос res.php с паузами, а не одиночный запрос — решение занимает секунды, а не миллисекунды.
  • Обработка тайм-аута и повторной попытки на случай, если CAPCHA_NOT_READY держится дольше обычного.

Где боты чаще всего упираются в CAPTCHA

Пять типичных сценариев:

Сценарий Типичная CAPTCHA Метод CaptchaAI
Отправка формы reCAPTCHA v2 method=userrecaptcha
Регистрация аккаунта reCAPTCHA v2/v3 method=userrecaptcha
Массовый ввод данных Капча-изображение method=base64
Бронирование Cloudflare Turnstile method=turnstile
Доступ к API-шлюзу Cloudflare Challenge method=cloudflare_challenge

Сколько потоков нужно боту

CaptchaAI тарифицирует по потокам, а не по числу решённых капч, поэтому расчёт до старта простой:

  • Один бот с последовательными запросами — это один поток.
  • Пять параллельных ботов на пике трафика обычно закрывает план BASIC ($15/мес, 5 потоков) с запасом.
  • Счёт в долларах не меняется от количества заявок в пиковый час — тариф привязан к потокам, а не к объёму решённых CAPTCHA.

Универсальный каркас: один класс на все типы CAPTCHA

Соберите один класс, который отправляет любую капчу в CaptchaAI и дожидается токена — каждый бот вызывает один и тот же метод solve():

import requests
import time
import logging

logger = logging.getLogger(__name__)

class CaptchaBot:
    def __init__(self, api_key):
        self.api_key = api_key
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        })

    def solve(self, method, **params):
        """Solve any CAPTCHA type."""
        params["key"] = self.api_key
        params["method"] = method

        resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
        if not resp.text.startswith("OK|"):
            raise Exception(f"Submit error: {resp.text}")

        task_id = resp.text.split("|")[1]
        logger.info(f"Task submitted: {task_id}")

        for _ in range(60):
            time.sleep(5)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key, "action": "get", "id": task_id
            })
            if result.text == "CAPCHA_NOT_READY": continue
            if result.text.startswith("OK|"): return result.text.split("|")[1]
            raise Exception(f"Error: {result.text}")

        raise TimeoutError("CAPTCHA solve timed out")

    def submit_form(self, url, form_data, captcha_field="g-recaptcha-response",
                    site_key=None, captcha_method="userrecaptcha"):
        """Submit a form with CAPTCHA solving."""
        if site_key:
            if captcha_method == "userrecaptcha":
                token = self.solve(captcha_method, googlekey=site_key, pageurl=url)
            elif captcha_method == "turnstile":
                token = self.solve(captcha_method, sitekey=site_key, pageurl=url)
            form_data[captcha_field] = token

        return self.session.post(url, data=form_data)

Что делает класс:

  • solve() — универсальная отправка и опрос: один метод обслуживает любой тип CAPTCHA из таблицы выше.
  • submit_form() — берёт site_key и pageurl страницы, получает токен и сразу подставляет его в нужное поле формы.

Пример 1 — бот, который сам проходит форму с reCAPTCHA

Контактная форма, закрытая reCAPTCHA v2 — CaptchaBot решает капчу и подставляет токен в запрос.

bot = CaptchaBot("YOUR_API_KEY")

# Submit a contact form protected by reCAPTCHA
result = bot.submit_form(
    url="https://example.com/contact",
    form_data={
        "name": "John Doe",
        "email": "[email protected]",
        "message": "Inquiry about your service"
    },
    site_key="6Le-wvkS...",
    captcha_method="userrecaptcha"
)

print(f"Form submitted: {result.status_code}")

На что обратить внимание:

  • site_key берётся из атрибута data-sitekey виджета на странице — его нужно найти до вызова solve().
  • Токен подставляется в то же поле, что ждёт форма (g-recaptcha-response для reCAPTCHA), иначе сервер отклонит отправку.

Пример 2 — многошаговый сценарий бронирования

Бот проходит шаги выбора даты и ввода данных и решает CAPTCHA только на последнем — на подтверждении:

def appointment_booking_bot(date, time_slot, user_info):
    bot = CaptchaBot("YOUR_API_KEY")

    # Step 1: Load booking page
    page = bot.session.get("https://example.com/book")

    # Step 2: Select date and time
    resp = bot.session.post("https://example.com/book/select", data={
        "date": date,
        "time": time_slot
    })

    # Step 3: Fill personal info with CAPTCHA
    result = bot.submit_form(
        url="https://example.com/book/confirm",
        form_data={
            "name": user_info["name"],
            "email": user_info["email"],
            "phone": user_info["phone"],
            "date": date,
            "time": time_slot
        },
        site_key="6Le-wvkS...",
        captcha_method="userrecaptcha"
    )

    return result.status_code == 200

# Run
success = appointment_booking_bot(
    date="2025-02-15",
    time_slot="10:00",
    user_info={"name": "John Doe", "email": "[email protected]", "phone": "555-0100"}
)

Почему CAPTCHA решается только на последнем шаге:

  • Промежуточные шаги (выбор даты, ввод данных) обычно не защищены — капча стоит перед финальной отправкой.
  • Решать её раньше времени бессмысленно: токен CAPTCHA действует ограниченное время и может истечь до момента реальной отправки формы.

Пример 3 — ввод данных с капчей-изображением

Порталы ввода данных чаще защищены капчей-изображением: бот кодирует картинку в base64 и передаёт в method=base64. Если бот сохраняет чужие данные — собирайте только то, что вправе обрабатывать по 152-ФЗ:

import base64

def data_entry_bot(entries, captcha_image_url):
    bot = CaptchaBot("YOUR_API_KEY")

    for entry in entries:
        # Load the form page
        page = bot.session.get("https://portal.example.com/entry")

        # Download and solve image CAPTCHA
        img = bot.session.get(captcha_image_url)
        img_b64 = base64.b64encode(img.content).decode()
        captcha_text = bot.solve("base64", body=img_b64)

        # Submit entry
        resp = bot.session.post("https://portal.example.com/entry", data={
            **entry,
            "captcha": captcha_text
        })

        logger.info(f"Entry submitted: {resp.status_code}")
        time.sleep(random.uniform(2, 5))

Что важно в этом сценарии:

  • Картинка передаётся в body уже закодированной в base64 — скачивать и сохранять файл на диск не нужно.
  • Пауза между записями снижает риск упереться в ограничение частоты запросов на самом портале, а не только на стороне CaptchaAI.

Тот же каркас на Node.js

Логика та же — отправить, опросить, получить токен:

const axios = require("axios");

class CaptchaBot {
  constructor(apiKey) {
    this.apiKey = apiKey;
  }

  async solve(method, params) {
    params.key = this.apiKey;
    params.method = method;

    const submit = await axios.get("https://ocr.captchaai.com/in.php", {
      params,
    });
    const taskId = submit.data.split("|")[1];

    while (true) {
      await new Promise((r) => setTimeout(r, 5000));
      const result = await axios.get("https://ocr.captchaai.com/res.php", {
        params: { key: this.apiKey, action: "get", id: taskId },
      });
      if (result.data === "CAPCHA_NOT_READY") continue;
      if (result.data.startsWith("OK|")) return result.data.split("|")[1];
      throw new Error(result.data);
    }
  }

  async submitForm(url, formData, siteKey, method = "userrecaptcha") {
    const token = await this.solve(method, {
      googlekey: siteKey,
      pageurl: url,
    });
    formData["g-recaptcha-response"] = token;

    return axios.post(url, new URLSearchParams(formData));
  }
}

// Usage
const bot = new CaptchaBot("YOUR_API_KEY");
const result = await bot.submitForm(
  "https://example.com/submit",
  { name: "John", email: "[email protected]" },
  "6Le-wvkS..."
);

Отличие от Python-версии минимальное — axios вместо requests, async/await вместо синхронных вызовов, но структура запроса и порядок опроса res.php те же.

Частые сбои и что с ними делать

Ниже — сбои, с которыми боты сталкиваются чаще всего в проде, и что с ними делать без переписывания каркаса:

Проблема Решение
Токен CAPTCHA отклонён Используйте токен в течение 120 секунд после решения.
Бот распознаётся, хотя токен верный Приблизьте заголовки и паузы между действиями к поведению обычного браузера.
Форма требует дополнительных полей Проверьте форму на скрытые поля — обычно это CSRF-токен.
Повторные отправки упираются в ограничение частоты Добавьте задержки и распределите нагрузку через несколько прокси.

Часто задаваемые вопросы

Сколько типов CAPTCHA реально закрывает один бот на CaptchaAI?

12 типов в GA (reCAPTCHA, Turnstile, Challenge, GeeTest v3, капча-изображение, grid-image, BLS) плюс CaptchaFox, Friendly Captcha и Lemin в бета-статусе.

Можно ли обрабатывать несколько ботов одновременно на одном API-ключе?

Да, лимит идёт по числу потоков в плане, а не по числу ботов или ключей.

Что делать, если res.php подолгу отвечает CAPCHA_NOT_READY?

Для reCAPTCHA v2 это нормально в пиковой нагрузке — опрос рассчитан на 60 попыток с паузой 5 секунд. Если тайм-аут регулярный, проверьте sitekey и pageurl.

Нужно ли ставить бота на паузу, пока CaptchaAI решает капчу?

Запрос к res.php неблокирующий, но опрос выше синхронный. При десятках ботов в процессе вынесите solve() в очередь.

Что делать, если сайт использует reCAPTCHA v3, а не v2?

Передайте в solve() дополнительно version=v3 и action — остальной каркас не меняется, submit_form() подставит токен в то же поле.

Похожие материалы

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