Comparisons

headless-режим и headed Chrome для решения CAPTCHA

CaptchaAI работает одинаково в headless- и headed-режиме: API решает CAPTCHA на сервере, и видимость окна браузера тут ни при чём. А вот антибот-системам сайта разница видна сразу.

  • CaptchaAI решает CAPTCHA одинаково в обоих режимах — разница только в том, что видит сайт.
  • Headless быстрее и легче по памяти, но выше шанс детекта и ниже score reCAPTCHA v3.
  • Headed выглядит как реальный пользователь и даёт высокий score, но требует вдвое больше памяти и дисплей на сервере.
  • Headed-режим стоит включать точечно — там, где детект headless реально мешает.

Headless или headed: сравнение в цифрах

Фактор Headless-режим Headed-режим
Скорость Быстрее (без рендеринга интерфейса) Медленнее (отрисовывает UI)
Память ~100–200 МБ ~300–500 МБ
Развёртывание на сервере Работает «из коробки» Нужен виртуальный дисплей (Xvfb)
Детект CAPTCHA Высокий (заметные сигналы) Низкий (похож на реального пользователя)
Оценка reCAPTCHA v3 0,1–0,3 (диапазон бота) 0,7–0,9 (диапазон человека)
Отладка Сложнее (нет визуального вывода) Проще (видно страницу)
Масштабирование Отличное (мало ресурсов) Ресурсоёмкое

Какой режим выбрать

Берите headless-режим, если:

  • Запускаете на сервере или в CI без дисплея
  • Масштабируетесь до 50+ параллельных сессий
  • Память ограничена
  • CaptchaAI и так решает все CAPTCHA — режим браузера на результат не влияет

Берите headed-режим, если:

  • Нужна визуальная отладка потока с CAPTCHA
  • Важна оценка reCAPTCHA v3 (headed-режим стабильно даёт более высокие баллы)
  • Целевой сайт блокирует именно headless
  • Скрипт и так запускается на машине с дисплеем

Берите headed-режим + виртуальный дисплей, если:

  • На сервере без дисплея нужно поведение браузера, близкое к headed-режиму
  • reCAPTCHA v3 стабильно даёт низкие оценки в headless-режиме именно на этом сайте
  • Бюджет позволяет выделить вдвое больше памяти на сессию

Как антибот-системы вычисляют headless Chrome

Какие сигналы проверяют

// Tests that CAPTCHA systems run

// 1. WebDriver flag (biggest tell)
navigator.webdriver  // true in headless, undefined in real browser

// 2. Chrome object completeness
window.chrome        // Missing or incomplete in headless

// 3. Plugins
navigator.plugins.length  // 0 in headless, 3+ in headed

// 4. WebGL renderer
// Headless: "SwiftShader Renderer"
// Headed:   "ANGLE (NVIDIA GeForce GTX 1080...)"

// 5. User-Agent contains "Headless"
navigator.userAgent.includes("Headless")  // Old Chrome versions

// 6. Screen dimensions
screen.width === 0   // Some headless configs

// 7. Notification permission
Notification.permission  // "denied" in headless without override

Результаты тестов на детект

Signal               Headed    Headless   New Headless (v112+)
─────────────────────────────────────────────────────────────
webdriver            false     true       true
chrome object        full      partial    improved
plugins              5         0          0
WebGL renderer       ANGLE     Swift      Swift
screen.width         1920      800        800
UA "HeadlessChrome"  no        yes        no (removed)

Поиск неисправностей

  1. Headless вычисляется по сигналам — сайт видит флаг navigator.webdriver. Используйте патчи совместимости или CDP-патчи.
  2. Низкая оценка v3 в headless — не хватает сигналов реального рендеринга. Переключитесь на headed-режим + Xvfb.
  3. Xvfb падает при запуске — конфликт номеров дисплея. Используйте --auto-servernum.
  4. Высокое потребление памяти в headed-режиме — активен процесс GPU. Добавьте флаг --disable-gpu.
  5. Скриншоты пустые в headless-режиме — неверный размер окна. Задайте --window-size=1920,1080.

Новый headless-режим Chrome (v112+)

В Chrome 112+ появился флаг --headless=new, который использует тот же движок рендеринга, что и headed-режим:

from selenium import webdriver

# Old headless (more detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless")  # Legacy mode

# New headless (less detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")  # Shares headed rendering

driver = webdriver.Chrome(options=options)

Новый headless-режим закрывает часть векторов детекта, но флаг navigator.webdriver и пустой список плагинов остаются.


Тесты производительности

Сценарий Headless-режим Headed-режим Headed-режим + Xvfb
Время запуска ~1 с ~2 с ~2,5 с
Память на вкладку 100–200 МБ 300–500 МБ 300–500 МБ
Загрузка страницы (среднее) 1,5 с 2,5 с 2,5 с
Оценка reCAPTCHA v3 0,1–0,3 0,7–0,9 0,5–0,8
Макс. параллельно (8 ГБ) 30–40 10–15 10–15
Доля решённых CAPTCHA Одинаковая (API) Одинаковая (API) Одинаковая (API)

На VPS с 8 ГБ памяти в Европе или Казахстане headed-режим + Xvfb даёт 10–15 сессий вместо 30–40 в headless. При оплате VPS в USD и ограниченном бюджете разумнее держать headless по умолчанию и включать headed точечно — там, где score reCAPTCHA v3 на конкретном сайте реально низкий.


headless-режим + CaptchaAI на Python

CaptchaAI одинаково хорошо работает в headless-режиме: решение CAPTCHA происходит на стороне API, а не в браузере:

import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

API_KEY = "YOUR_API_KEY"
API_URL = "https://ocr.captchaai.com"


def create_headless_driver():
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("--window-size=1920,1080")
    options.add_argument(
        "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
    )
    return webdriver.Chrome(options=options)


def solve_captcha(site_url, sitekey):
    resp = requests.post(f"{API_URL}/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": site_url,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        resp = requests.get(f"{API_URL}/res.php", params={
            "key": API_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = resp.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("Solve timeout")


# Full headless workflow
driver = create_headless_driver()

try:
    driver.get("https://example.com/form")
    time.sleep(2)

    sitekey = driver.execute_script(
        "return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
    )

    if sitekey:
        token = solve_captcha(driver.current_url, sitekey)
        driver.execute_script(f"""
            document.querySelector('#g-recaptcha-response').value = '{token}';
        """)
        driver.find_element(By.CSS_SELECTOR, "form").submit()

finally:
    driver.quit()

Headed-режим на серверах (виртуальный дисплей)

Запустить headed Chrome можно и на сервере без монитора — через виртуальный дисплей Xvfb.

Установите Xvfb на Linux и запустите скрипт под виртуальным дисплеем одной командой:

# Install
sudo apt-get install xvfb

# Run with virtual display
xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" python script.py

Для управления дисплеем прямо из Python-скрипта, без отдельной команды xvfb-run, используйте PyVirtualDisplay:

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(1920, 1080))
display.start()

options = webdriver.ChromeOptions()
# No --headless flag = headed mode in virtual display
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome(options=options)
# Now runs headed Chrome with real rendering, but no physical display

В Docker Xvfb ставится прямо в образ, а команда запуска контейнера оборачивается в xvfb-run:

FROM python:3.12-slim

RUN apt-get update && apt-get install -y \
    xvfb \
    chromium \
    chromium-driver \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . /app
WORKDIR /app

CMD ["xvfb-run", "--auto-servernum", "python", "main.py"]

Патчи совместимости для headless (Node.js)

Пакет puppeteer-extra с плагином патчей убирает признаки автоматизации — пустой navigator.plugins, флаг navigator.webdriver:

const puppeteer = require("puppeteer-extra");
const StealthPlugin = require("puppeteer-extra-plugin-stealth");

puppeteer.use(StealthPlugin());

async function headlessStealth() {
  const browser = await puppeteer.launch({
    headless: "new",
    args: [
      "--no-sandbox",
      "--window-size=1920,1080",
      "--disable-blink-features=AutomationControlled",
    ],
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });

  // Additional stealth patches
  await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, "webdriver", {
      get: () => undefined,
    });

    Object.defineProperty(navigator, "plugins", {
      get: () => [1, 2, 3, 4, 5],
    });
  });

  await page.goto("https://example.com/form");

  // Detect and solve CAPTCHA with CaptchaAI
  const sitekey = await page.evaluate(() =>
    document.querySelector("[data-sitekey]")?.getAttribute("data-sitekey")
  );

  if (sitekey) {
    // Call CaptchaAI API (see other guides for full implementation)
    const token = await solveCaptchaAI(page.url(), sitekey);

    await page.evaluate((t) => {
      document.querySelector("#g-recaptcha-response").value = t;
    }, token);
  }

  await browser.close();
}

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

Влияет ли режим браузера на то, как CaptchaAI решает CAPTCHA?

Нет. CaptchaAI решает CAPTCHA на своей стороне по sitekey и URL страницы — режим браузера значения не имеет.

Как понять, что сайт вычисляет именно headless Chrome, а не блокирует по другой причине?

Проверьте сигналы вручную: navigator.webdriver, длину navigator.plugins, строку WebGL-рендерера. Если вместо CAPTCHA сайт сразу отдаёт 403, дело обычно не в headless, а в rate limiting или блокировке по IP/прокси.

Правда ли, что --headless=new полностью снимает проблему детекта?

Нет. Движок рендеринга тот же, что у headed-режима, но флаг navigator.webdriver и пустой список плагинов остаются.

Оправдан ли headed-режим + Xvfb на VPS с ограниченной памятью?

Обычно да, если именно на этом сайте reCAPTCHA v3 даёт низкие оценки в headless. Прирост памяти — вдвое на сессию, поэтому чаще выгоднее включать headed точечно.

Нужно ли переписывать интеграцию с CaptchaAI при переключении между headless и headed?

Нет. Вызовы in.php/res.php и обработка токена (g-recaptcha-response для reCAPTCHA, cf-turnstile-response для Turnstile) не меняются.


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


Выберите режим браузера под свой сценарий CAPTCHA — получите ключ CaptchaAI и решайте CAPTCHA в любой конфигурации.

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