Headless-браузеры для парсинга JS-сайтов: когда простого запроса недостаточно
Оглавление
Современный веб всё чаще напоминает чёрный ящик: вы отправляете запрос, а в ответ получаете пустую оболочку, которая наполняется содержимым только после работы десятков скриптов. Для извлечения данных с таких сайтов простого HTTP-запроса уже недостаточно — нужна полноценная среда браузера. Разбираемся, как работают headless-браузеры и когда их использование оправдано.
Почему обычный запрос не подходит для JS-сайтов
Десять лет назад веб-страница в большинстве случаев представляла собой готовый HTML-документ. Сервер собирал всю информацию, вставлял её в шаблон и отправлял клиенту. Такой ответ легко парсился простым GET-запросом — нужные данные уже лежали в коде. Сегодня ситуация кардинально изменилась. Большая часть современного контента формируется динамически с помощью JavaScript уже в браузере пользователя. Сервер отдаёт лишь минимальный каркас — пустые контейнеры и ссылки на скрипты. Сами скрипты загружаются, выполняются и уже после этого наполняют страницу текстом, изображениями, таблицами.
Когда вы отправляете обычный HTTP-запрос (например, через curl или библиотеку requests), вы получаете именно этот пустой каркас — то, что приходит до выполнения JavaScript. Все данные, которые подгружаются асинхронно через fetch или XMLHttpRequest, остаются за кадром. В результате парсер видит пустой div вместо каталога товаров, undefined вместо цены и «Загрузка...» вместо описания. Сайты на React, Vue, Angular и многих других SPA-фреймворках практически бесполезны для парсинга без выполнения скриптов.
Что вообще делает headless-браузер иначе, чем обычный HTTP-запрос
Headless-браузер — это полноценный браузер без графического интерфейса. Он точно так же загружает HTML, парсит CSS, выполняет JavaScript, обрабатывает события и хранит состояние страницы в DOM. Разница лишь в том, что вы не видите окна, а управляете браузером программно. Процесс выглядит так: вы передаёте URL, headless-браузер открывает страницу, ждёт, пока все скрипты загрузятся и отработают (включая таймауты и асинхронные запросы к API), формирует итоговый DOM, и только после этого вы забираете данные — через DOM-запросы, снимки экрана или перехват сетевых ответов.
Именно это отличает headless-подход от простого HTTP-запроса: он воспроизводит полный жизненный цикл страницы так, как это делает браузер реального пользователя. Для парсинга это означает, что вы получаете те же данные, которые видит человек на экране: каталог товаров после пагинации, цену с учётом скидки, подгруженную по скроллу ленту. Кроме того, headless-браузеры умеют взаимодействовать со страницей — кликать по кнопкам, заполнять формы, скроллить, переключать вкладки. Это открывает доступ к данным, которые в принципе не получить одним запросом, потому что они появляются только после пользовательских действий.
Selenium, Puppeteer, Playwright — в чём разница на практике
На рынке headless-инструментов доминируют три решения, и выбор между ними во многом определяет скорость разработки и стоимость поддержки парсера.
Selenium — самый старый из трёх (первый релиз в 2004 году). Он поддерживает больше всего языков программирования: Java, Python, C#, Ruby, JavaScript, Kotlin, PHP и другие. Работает с Chrome, Firefox, Edge и Safari. Механизм общения с браузером — протокол WebDriver. Именно этот слой прокси делает Selenium заметно медленнее конкурентов: каждая команда проходит через WebDriver, который преобразует её в действия браузера. Архитектура Selenium сложнее, настройка требует установки отдельных драйверов для каждого браузера. В сообществе Selenium считается зрелым и надёжным, но часто неоправданно тяжёлым для задач чистого парсинга.
Puppeteer — инструмент от Google, который работает только с JavaScript/Node.js и преимущественно с Chrome/Chromium. Он общается с браузером напрямую через Chrome DevTools Protocol (CDP), без посредников. Это даёт прирост скорости по сравнению с Selenium и более простую установку — драйвер встроен в библиотеку. Puppeteer отлично подходит для одностраничных приложений и задач, где код пишется на JavaScript. Его главный минус — привязка к стеку Node.js и к Chromium: если нужны Firefox или Safari, Puppeteer не подходит.
Playwright — сравнительно молодой инструмент от той же команды, что создала Puppeteer, но изначально спроектированный как кроссплатформенное решение. Поддерживает несколько языков: JavaScript/TypeScript, Python, .NET, Java. Работает с тремя движками: Chromium, Firefox и WebKit. Ключевое преимущество Playwright — встроенное автоматическое ожидание готовности элементов. Вам не нужно вручную прописывать time.sleep или WebDriverWait — библиотека сама дожидается, когда элемент появится в DOM, станет видимым или доступным для взаимодействия. По общему мнению индустрии, для новых проектов Playwright чаще всего оказывается наиболее удобным и надёжным выбором из трёх.
Важно понимать: точных независимых замеров скорости и потребления ресурсов между этими инструментами в открытых источниках нет. Экспертное сообщество сходится в том, что Playwright и Puppeteer быстрее Selenium, но это качественная оценка, а не точно измеренная разница. Поэтому не стоит верить цифрам вида «Puppeteer в 2 раза быстрее» — такие утверждения почти всегда являются маркетинговыми заявлениями поставщиков или результатом частных тестов с определёнными условиями.
Какой инструмент когда выбрать
Выбор инструмента для парсинга JS-сайтов зависит от стека технологий проекта, требований к браузерному покрытию и квалификации команды. Если ваш проект написан на Python и нужен доступ только к Chrome — можно использовать Selenium с ChromeDriver. Однако Selenium здесь будет самым медленным вариантом. Лучше взять Playwright для Python: он быстрее, проще в настройке и уже включает автоматическое ожидание, что снижает количество падающих скриптов.
Если проект на Node.js, а целевые сайты — исключительно на Chrome/Chromium (то есть не требуется тестирование в Firefox или Safari), Puppeteer будет оптимальным выбором: лёгкий, быстрый, с минимальным порогом входа. Для проектов, где важно кроссплатформенное покрытие (например, парсинг одного и того же сайта в разных браузерах для обхода антибот-систем), Playwright — единственный адекватный выбор из трёх.
В отдельных случаях головную боль может доставлять обнаружение автоматизации — многие антибот-системы умеют распознавать presence of automation tools. Существуют вспомогательные обёртки и библиотеки, которые перехватывают и анализируют HTTP-запросы внутри headless-сессии, а также инструменты, маскирующие сам факт автоматизации браузера. Но это уже тема для отдельного разговора.
Оборотная сторона: headless-парсинг требует больше ресурсов и сложнее в поддержке
За возможность выполнять JavaScript приходится платить. Headless-браузер — это полноценный браузер, он потребляет заметно больше оперативной памяти на один экземпляр, чем простой HTTP-клиент, и нагружает процессор при выполнении скриптов страницы. Если нужно парсить сотни или тысячи страниц одновременно, потребуется либо мощный сервер, либо эффективное управление очередью и пулом браузеров. Простой HTTP-запрос обрабатывает страницы быстро и почти не нагружает процессор. Headless-браузер на той же машине заметно медленнее и требовательнее к ресурсам.
Вторая проблема — нестабильность. Сайты с JavaScript сложнее поддаются парсингу: добавление случайного таймаута, смена CDN, обновление библиотек на стороне сайта могут сломать ваш парсер. То, что вчера работало с автоматическим ожиданием Playwright, сегодня может падать, потому что страница начала загружать данные по-другому. Парсинг через headless-браузер требует постоянного мониторинга и адаптации под изменения целевого сайта.
Кроме того, использование headless-браузера не делает парсинг автоматически законным. Как и при любом другом способе сбора данных, необходимо соблюдать правовые ограничения. Сервис webparser.site работает только с общедоступными данными, не собирает персональные данные без явного основания и уважает защиту баз данных по ст. 1334-1335.1 ГК РФ (порог в 10 тысяч элементов). Headless-браузер не даёт права обходить технические меры защиты — это может быть квалифицировано по ст. 272 УК РФ. Инструмент — лишь средство, а не индульгенция.
Headless-браузеры решают проблему, с которой обычные HTTP-запросы не справляются в принципе. Но их применение должно быть оправдано реальной необходимостью (наличие динамического контента, сложное взаимодействие). Если сайт отдаёт данные в готовом HTML — нет смысла запускать браузер. Если без JavaScript ничего не работает — выбор между Selenium, Puppeteer и Playwright становится вопросом цены разработки, скорости работы и того, насколько часто сайт меняет своё поведение. Последний пункт, кстати, часто оказывается важнее первых двух.
Частые вопросы
Среди услуг — мониторинг цен (от 3 000 руб/мес), разработка парсера на заказ (от 15 000 руб), парсинг товаров и сайтов (от 5 000 руб за разовую задачу), парсинг маркетплейсов и Telegram-каналов (от 4 000 и 3 500 руб/мес соответственно), а также сбор баз организаций с карт (от 6 000 руб). Данные поставляются в форматах Excel, CSV или Google Sheets, а по запросу возможна интеграция с вашей системой.
Обычный запрос забирает лишь пустой HTML-каркас, потому что современный контент часто подгружается через JavaScript. Headless-браузер выполняет этот скрипт, как настоящий браузер, и выдаёт ту же страницу, которую видит живой посетитель — это единственный способ распарсить JS-сайты.
Наиболее популярны Selenium, Puppeteer и Playwright. Playwright считается самым современным: он поддерживает несколько языков и браузерных движков, имеет встроенное ожидание элементов. Если вам нужно решение с максимальной совместимостью — выбирайте Selenium, но он медленнее. Для быстрой настройки на Node.js — Puppeteer.
Мы работаем только с общедоступными данными, не собираем персональные данные без явного основания (152-ФЗ) и уважаем защиту баз данных (ст. 1334-1335.1 ГК РФ, порог в 10 000 элементов). Также мы не обходим технические меры защиты, чтобы не нарушать ст. 272 УК РФ. Это гарантирует легальность вашего сбора информации.
Не нашли ответ на свой вопрос? Задайте вопрос — ответим напрямую.