Headless Chrome в автоматизації: що насправді видає бота

Headless Chrome в автоматизації: що насправді видає бота

27.05.2026

Headless Chrome сам по собі не є «поганим». Це нормальний режим Chrome без видимого вікна. Його використовують для тестів, генерації PDF, скриншотів, моніторингу та внутрішньої автоматизації.

Проблеми починаються в іншому місці: коли браузер у режимі headless намагаються видати за звичайного користувача на сайті з антифродом. Тоді сайт дивиться не на один параметр, а на всю картину: як запущений браузер, хто ним керує, які API доступні, як виглядає графіка, чи збігається мережа з профілем, і чи є ознаки того, що браузером керують Playwright, Puppeteer або Selenium.

Важливий момент: старі статті про Headless Chrome застарівають. Google оновив headless-режим у Chrome 112: тепер Chrome створює справжні платформні вікна, просто не показує їх. У документації Chrome це описано прямо: Chrome Headless mode. Там само сказано, що старий headless-режим починаючи з Chrome 132 винесено в окремий chrome-headless-shell. Тому сьогодні чесніше формулювати так: новий Headless Chrome став ближчим до звичайного Chrome, але автоматизація все одно залишає свої сліди.

Перший очевидний сигнал: navigator.webdriver

navigator.webdriver — це стандартний сигнал автоматизації.

У специфікації W3C WebDriver є окремий розділ про webdriver-прапорець: WebDriver specification. MDN пояснює простіше: властивість navigator.webdriver показує, що user agent контролюється автоматизацією, а в Chrome вона стає true, наприклад, при --enable-automation, --headless або деяких варіантах remote debugging: Navigator.webdriver.

Для звичайного QA-тесту це нормально. Для акаунтів, платежів, рекламних кабінетів, маркетплейсів та інших risk-based систем це сильний сигнал. Він не обов’язково єдиний. Але якщо сайт бачить navigator.webdriver === true, йому вже не потрібно довго гадати, що перед ним.

Чому просто приховати webdriver недостатньо

Багато хто починає з простого патча:

Object.defineProperty(navigator, 'webdriver', {
  get: () => undefined
})

Проблема в тому, що сайт може дивитися глибше. Він може перевіряти прототипи, властивості, поведінку iframe, помилки, stack trace, плагіни, PDF viewer, WebGL, розміри вікна, media devices і десятки інших дрібниць.

І головне: якщо ви виправили один параметр, але зламали узгодженість, стало тільки гірше. Наприклад:

  • navigator.webdriver прихований, але CDP-клієнт усе ще можна визначити;
  • User-Agent схожий на звичайний Chrome, але HTTP-заголовки все одно виглядають дивно;
  • профіль заявляє macOS, а WebGL і шрифти схожі на Linux-контейнер;
  • viewport, screen, outerWidth, touch-сигнали та device scale factor не збігаються між собою.

Цю логіку добре видно в дослідженні FP-Inconsistent. Автори вивчали evasive bot traffic і показали, що ботів часто видає не один «червоний прапор», а неузгодженість fingerprint-атрибутів між собою і в часі.

CDP: невидимий пульт керування, який теж можна помітити

Puppeteer і Playwright переважно керують Chromium через Chrome DevTools Protocol. Це офіційний протокол для інспекції, налагодження та керування браузером: Chrome DevTools Protocol. У документації Chrome DevTools також прямо сказано, що DevTools використовує CDP для instrument, inspect, debug і profile браузерів: Protocol monitor.

Для розробника CDP зручний. Для антибота це важливий шар перевірки.

У розборі 2024 року DataDome пише, що новий Headless Chrome став значно ближчим до звичайного Chrome з погляду fingerprint, тому увага змістилася до CDP-сигналів: How New Headless Chrome & the CDP Signal Are Impacting Bot Detection. Сенс простий: якщо браузер виглядає майже звичайним, сайт перестає шукати саме «headless» і починає шукати ознаки того, що браузером керує автоматизація.

CDP-детект теж змінюється, і деякі старі методи перестають працювати. Castle, наприклад, розбирав, чому один класичний CDP-сигнал із часом зламався: Why a classic CDP bot detection signal suddenly stopped working. Але загальний висновок лишається тим самим: шар керування браузером — це окрема поверхня для детекту.

Чому stealth-плагіни не вирішують проблему назавжди

puppeteer-extra-plugin-stealth і схожі бібліотеки корисні як швидкий шар evasions. Вони патчать відомі сигнали: navigator.webdriver, navigator.plugins, WebGL vendor, chrome.runtime, iframe.contentWindow, codecs та інші речі. Це видно навіть із README проєкту: puppeteer-extra-plugin-stealth.

Але такий підхід залишається реактивним. Спочатку з’являється детект, потім під нього пишуть evasion. Потім антибот перевіряє сам evasion або шукає новий побічний ефект. Це звичайна гонка озброєнь.

DataDome також окремо розбирав детект Puppeteer Extra Stealth через JavaScript browser fingerprinting: Detecting Headless Chrome’s Puppeteer Extra Stealth Plugin. Не обов’язково погоджуватися з кожною деталлю тієї статті. Важливий сам факт: публічний stealth-плагін — це публічний проєкт. Його код можуть читати обидві сторони.

Що найчастіше видає headless-автоматизацію

На практиці фраза «headless палиться» зазвичай означає не якийсь один конкретний прапорець, а набір дрібних нестикувань.

Найчастіші групи сигналів:

  • automation-flags: navigator.webdriver, launch flags, remote debugging;
  • CDP/DevTools-методи;
  • WebGL і Canvas, які не збігаються із заявленою ОС і пристроєм;
  • порожні або дивні plugins, mimeTypes, PDF viewer і media devices;
  • неприродні розміри вікна та екрана;
  • відсутність нормальної історії профілю, cookies, storage і permissions;
  • мережеві нестикування: IP, DNS, WebRTC, часовий пояс, locale;
  • поведінка: занадто рівні таймінги, миттєві кліки, однакові сценарії.

Тому заміна User-Agent і проксі не перетворює headless на живого користувача. Вона лише змінює два параметри у великій системі скорингу.

Як ми підходимо до автоматизації в 0detect

У 0detect ми не намагаємося «сховати headless» однією настройкою. Наша задача — дати автоматизації цілісний браузерний профіль.

Практично це виглядає так: автоматизація запускає не порожній браузер «з нуля», а конкретний профіль 0detect. У нашій документації з Local API показано базовий сценарій: спочатку отримати ID профілю, потім запустити браузер за цим ID, після чого 0detect повертає devToolsActivePort. До цього порту вже можна підключити Selenium або інший automation-клієнт: Запуск браузера.

Тобто Selenium, Playwright, Puppeteer або інший automation-клієнт відповідає за бізнес-логіку: відкрити сторінку, натиснути кнопку, заповнити форму, зібрати дані. А шар профілю відповідає за те, щоб браузер виглядав узгоджено:

  • один і той самий профіль зберігає стабільний відбиток;
  • графіка, шрифти, екран, мова, часовий пояс і мережа узгоджені між собою;
  • automation-патерни не «лікуються» випадковими JS-патчами на сторінці;
  • проксі, DNS і WebRTC працюють в одній логіці з профілем;
  • поведінку можна масштабувати, не перетворюючи всі сесії на копії одна одної.

У Local API також є можливість працювати з проксі: створити proxy, прив’язати його до профілю через POST /profile/set/proxy, а вже потім запускати браузер: Робота з proxy. Це важливо для автоматизації, тому що мережеві налаштування мають бути частиною профілю ще до запуску, а не випадковою надбудовою поверх уже відкритого Chrome.

Це особливо важливо для довгоживучих акаунтів. Одноразовий скрипт інколи може пройти просто на везінні. Але якщо профіль має жити тижнями, повертатися на той самий сайт, зберігати історію і не викликати зайвих перевірок, йому потрібна стабільність.

Підсумок

Headless Chrome став кращим. Стара теза «headless завжди легко детектиться» тепер уже надто груба. Новий headless ближчий до звичайного Chrome, і це підтверджує сама документація Chrome.

Але «ближчий» не означає «невідрізний». Автоматизацію все ще видно через navigator.webdriver, CDP, неузгоджені fingerprint-атрибути, мережеві витоки й поведінку.

Нормальна стратегія — не латати один прапорець за іншим, а будувати цілісний профіль: браузер, графіка, мережа, storage, таймінги й automation-шар мають виглядати як одне реальне середовище.

Недавние статьи

Почему одинаковые антидетект-профили дают разные результаты при масштабировании
Почему одинаковые антидетект-профили дают разные результаты при масштабировании
Есть ситуация, которую проходят почти все команды, работающие с мультиаккаунтингом. Настраиваешь профили, тестируешь на небольшом объёме — всё работает стабильно. Масштабируешь: берёшь тот же шаблон, запускаешь сотню аккаунтов — и результаты начинают расходиться. Одни профили работают без проблем, другие получают дополнительные проверки или уходят в блок. В интерфейсе антидетект-браузера все настройки выглядят одинаково. Первая реакция […]
27.05.2026
WebRTC и DNS: почему одного прокси мало
WebRTC и DNS: почему одного прокси мало
Прокси скрывает реальный IP адрес для HTTP/HTTPS-трафика браузера. Но у браузера есть и другие “способы” сообщить свой реальный IP. Два из них стоит проверять отдельно: WebRTC и DNS. WebRTC и DNS — это нормальные части браузера и сети. Проблема начинается, когда сетевые проверки показывают не согласоввность: сайт открыт через прокси, но WebRTC или DNS leak-тест […]
27.05.2026
Headless Chrome в автоматизации: что реально выдаёт бота
Headless Chrome в автоматизации: что реально выдаёт бота
Headless Chrome сам по себе не «плохой». Это нормальный режим Chrome без видимого окна. Его используют для тестов, генерации PDF, скриншотов, мониторинга и внутренней автоматизации. Проблемы начинаются в другом месте: когда браузер в режиме headless пытаются выдать за обычного пользователя на сайте с антифродом. Тогда сайт смотрит не на один параметр, а на всю картину: […]
27.05.2026

Сделайте свою работу быстрой и безопасной с помощью 0DETECT Browser

Хотите быть в курсе всех новостей, скидок, акций? Подпишитесь на нашу рассылку и получайте самую свежую информацию первым
Следите за нами в социальных сетях
Изучите браузер 0DETECT