Comparisons

Текстовая CAPTCHA и графическая CAPTCHA: сравнение для разработчиков

Картинка с искажёнными буквами и поле ввода рядом — текстовая CAPTCHA: в автоматизации она закрывается одним запросом к OCR. Сетка фотографий с подписью «выберите все светофоры» — графическая CAPTCHA, для неё нужен решатель под конкретного провайдера. Разница в один экран интерфейса оборачивается разницей в объёме кода и во времени удержания потока.

Короткий ответ: что выбирать под свою задачу

  • Текстовая CAPTCHA — автономный фильтр спама без внешних зависимостей, с возможностью добавить аудиоверсию.
  • Графическая CAPTCHA — вход в личный кабинет и платежи, где допустимо большее трение ради управляемой защиты.
  • Ни та, ни другая, если трафик закрывают невидимые проверки: reCAPTCHA v3 и Cloudflare Turnstile не требуют действий пользователя и доступнее для людей с нарушениями зрения.

Прямое сравнение по десяти параметрам

Параметр Текстовая CAPTCHA Графическая CAPTCHA
Уровень защиты Низкий — стандартные наборы читает современный OCR Высокий — нужна классификация объектов
Время решения человеком 5–10 с 10–30 с
Доля ошибок у людей 15–20 % 8–15 %
Доступность Плохо для слабовидящих Ещё хуже: сетка непригодна для скринридеров
Мобильные устройства Средне — мелкие символы Хорошо — выбор касанием
Сложность автоматизации Низкая: один запрос к OCR Высокая: нужен решатель под провайдера
Стоимость внедрения Бесплатно, на своём сервере От бесплатного до платного SDK провайдера
Нагрузка на пул потоков Поток занят < 0,5 с (image/OCR) Дольше: grid image < 1 с, reCAPTCHA v2 < 60 с
Сбор данных Нет Может обучать ML-модели (reCAPTCHA)
Объём интеграции Минимальный — генерация картинки на бэкенде Средний — JavaScript SDK и токен

Строка про потоки важнее, чем кажется: тарифы CaptchaAI считаются по числу одновременных потоков, а не решений.

Как устроена текстовая CAPTCHA

Сервер рисует случайную строку как изображение и искажает её, чтобы помешать распознаванию.

Приёмы искажения

Приём Зачем нужен
Деформация символов Мешает простому распознаванию
Фоновый шум Линии, точки и градиенты за текстом
Наложение символов Ломает сегментацию букв
Рандомизация шрифтов Свой шрифт и кегль в каждой задаче
Вариация цвета Случайный цвет символов и фона

Жизненный цикл текстовой проверки

Server generates random string (e.g., "X7mK9p")
    ↓
Applies distortion: warping, noise, overlap
    ↓
Renders as PNG/JPEG image
    ↓
User reads characters, types into input field
    ↓
Server compares input against stored string (case-insensitive usually)

Компромисс очевиден: чем сильнее искажение, тем чаще ошибается не только машина, но и человек.

Как устроена графическая CAPTCHA

Здесь пользователь выбирает подходящие плитки в сетке, сверка идёт на стороне провайдера, а форма получает только токен.

Основные разновидности

Разновидность Задача пользователя Провайдер
Выбор в сетке «Выделите все квадраты со светофорами» reCAPTCHA v2
Разметка изображений «Нажмите на все изображения с автобусом» hCaptcha
Подсчёт объектов «Сколько велосипедов на изображении?» Самописные решения
Поворот «Поверните изображение в правильное положение» FunCaptcha

Жизненный цикл графической проверки

Server selects images from a labeled dataset
    ↓
Presents 3×3 or 4×4 grid with a text prompt
    ↓
User clicks matching images
    ↓
Server validates selections against ground truth
    ↓
If fading images: new images load in place of selected ones (multi-round)

Многораундовый сценарий превращает одну задачу в несколько последовательных.

Как определить тип CAPTCHA на странице

Тип проверки определяется по разметке: сначала маркеры провайдеров, затем связка «картинка со словом captcha в src» плюс «поле ввода с captcha в name» — почти всегда это самописная текстовая проверка.

Определение на Python

import requests
from bs4 import BeautifulSoup
import re

def detect_captcha_type(url):
    """Detect whether page uses text or image CAPTCHA."""
    response = requests.get(url, timeout=10)
    soup = BeautifulSoup(response.text, "html.parser")
    html = response.text

    result = {"text_captcha": False, "image_captcha": False, "provider": None}

    # Check for reCAPTCHA (image-based)
    if "google.com/recaptcha" in html or "g-recaptcha" in html:
        result["image_captcha"] = True
        result["provider"] = "reCAPTCHA"
        return result

    # Check for hCaptcha (image-based)
    if "hcaptcha.com" in html or "h-captcha" in html:
        result["image_captcha"] = True
        result["provider"] = "hCaptcha"
        return result

    # Check for text CAPTCHA patterns
    captcha_images = soup.find_all("img", attrs={
        "src": re.compile(r"captcha", re.I)
    })
    captcha_inputs = soup.find_all("input", attrs={
        "name": re.compile(r"captcha", re.I)
    })

    if captcha_images and captcha_inputs:
        # Image with text input = text CAPTCHA
        result["text_captcha"] = True
        result["provider"] = "custom text CAPTCHA"
        return result

    # Check for FunCaptcha (image-based rotation)
    if "funcaptcha" in html.lower() or "arkoselabs" in html.lower():
        result["image_captcha"] = True
        result["provider"] = "FunCaptcha"
        return result

    return result

captcha = detect_captcha_type("https://staging.example.com/qa-login")
print(captcha)

Определение на Node.js

const axios = require("axios");
const cheerio = require("cheerio");

async function detectCaptchaType(url) {
    const { data: html } = await axios.get(url, { timeout: 10000 });
    const $ = cheerio.load(html);

    const result = { textCaptcha: false, imageCaptcha: false, provider: null };

    // reCAPTCHA detection
    if (html.includes("google.com/recaptcha") || html.includes("g-recaptcha")) {
        result.imageCaptcha = true;
        result.provider = "reCAPTCHA";
        return result;
    }

    // hCaptcha detection
    if (html.includes("hcaptcha.com") || html.includes("h-captcha")) {
        result.imageCaptcha = true;
        result.provider = "hCaptcha";
        return result;
    }

    // Text CAPTCHA: image + input with "captcha" in name/class
    const captchaImgs = $("img[src*='captcha' i]").length;
    const captchaInputs = $("input[name*='captcha' i]").length;

    if (captchaImgs > 0 && captchaInputs > 0) {
        result.textCaptcha = true;
        result.provider = "custom text CAPTCHA";
        return result;
    }

    return result;
}

detectCaptchaType("https://staging.example.com/qa-login").then(console.log);

Решение текстовой CAPTCHA через OCR API CaptchaAI

Текстовая CAPTCHA остаётся изображением: искажённый текст приходит в браузер в PNG или JPEG. Отдельный «текстовый» метод не нужен — картинка уходит в OCR-эндпоинт как base64, а ответ возвращает распознанную строку.

import requests
import base64
import time

API_KEY = "YOUR_API_KEY"

# Get the CAPTCHA image
captcha_url = "https://example.com/captcha.png"
image_data = requests.get(captcha_url).content
b64 = base64.b64encode(image_data).decode()

# Submit to CaptchaAI
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "base64",
    "body": b64,
    "json": 1,
})
task_id = submit.json()["request"]

# Poll for result
for _ in range(30):
    time.sleep(3)
    resp = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    }).json()

    if resp.get("status") == 1:
        print(f"CAPTCHA text: {resp['request']}")
        break

in.php принимает задачу и возвращает её ID, res.php опрашивается до готовности, json: 1 избавляет от разбора текстового ответа. Image/OCR закрывает 27 500+ вариантов изображений и укладывается в < 0,5 с на задачу.

Что CaptchaAI решает, а что нет

Тип проверки Статус в CaptchaAI
Image / OCR, Grid Image, BLS ✅ есть, < 0,5–1 с
reCAPTCHA v2, v2 Invisible, v3 (+ Enterprise) ✅ есть
Cloudflare Turnstile и Challenge, GeeTest v3 ✅ есть
CaptchaFox, Friendly Captcha, Lemin ✅ beta
hCaptcha, FunCaptcha (Arkose Labs) ❌ пока нет
GeeTest v4 ❌ скоро, пока недоступно

Итого 15 методов: 12 в общем доступе и 3 в статусе beta.

Сценарий: ночной регресс на смешанных формах

Знакомая ситуация для команд в Москве, Минске и Алматы: порталу десять лет, новые разделы закрыты reCAPTCHA v2, а старые внутренние формы отдают самописную картинку с буквами. Ночной прогон идёт по обоим типам сразу, и потоки приходится считать по самому медленному:

  • текстовые формы держат поток меньше полсекунды — даже BASIC ($15/мес, 5 потоков) закрывает тысячи таких задач за считаные минуты;
  • формы с reCAPTCHA v2 держат поток дольше (< 60 с), узким местом становится параллельность — здесь логичнее STANDARD ($30/мес, 15 потоков);
  • в логах храните только те данные форм, которые вы вправе обрабатывать: 152-ФЗ и принцип минимизации из GDPR действуют для стендов так же, как для продакшена.

Частые вопросы

Как отличить текстовую CAPTCHA от reCAPTCHA, не открывая браузер?

По HTML. google.com/recaptcha или класс g-recaptcha указывают на reCAPTCHA, hcaptcha.com — на hCaptcha. Если маркеров провайдера нет, но есть картинка с captcha в src и поле ввода с captcha в name, это самописная текстовая проверка.

Сколько потоков нужно, чтобы закрывать тысячу текстовых проверок в час?

Немного. При решении image/OCR меньше полсекунды вы упрётесь в сетевые задержки раньше, чем в лимит потоков: пяти потоков тарифа BASIC ($15/мес) хватает с запасом. Наращивать тариф стоит, когда в прогоне появляются медленные типы вроде reCAPTCHA v2.

Почему распознавание ошибается на сильно искажённом тексте?

Искажение работает против любого читателя: наложенные символы и агрессивная деформация снижают долю успешных решений и у машины, и у человека. Практический вывод: закладывайте повторную попытку с новой картинкой.

Что делать, если форму закрывает hCaptcha или FunCaptcha?

Планировать этот участок отдельно: hCaptcha и FunCaptcha (Arkose Labs) в поддерживаемые типы не входят, GeeTest v4 заявлен как «скоро». Через API доступны:

  • reCAPTCHA v2/v3, Cloudflare Turnstile и Challenge, GeeTest v3;
  • image/OCR, grid image и BLS;
  • CaptchaFox, Friendly Captcha и Lemin — в статусе beta.

Что запомнить

Текстовая CAPTCHA дешева и во внедрении, и в автоматизации: одна картинка — один запрос к OCR API CaptchaAI. Графическая сложнее с обеих сторон: защита сильнее, но нужны SDK провайдера и отдельный решатель. Рынок смещается к невидимым проверкам: меньше трения для пользователя и работа с токеном вместо картинки для автоматизации.

Похожие статьи

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