Selenium

18 сентября 2026 · ~15 мин чтения

инструмент автоматизация браузер тестирование веб

Selenium

Selenium — набор инструментов, который позволяет программе управлять настоящим браузером: открывать страницы, кликать, вводить текст, читать содержимое. В основе лежит WebDriver — стандартизированный протокол, по которому твой код на Python, Java или JavaScript отдаёт браузеру команды через промежуточный драйвер.

История

Selenium родился из бытовой боли тестировщиков начала 2000-х. Веб-приложения перестали быть набором статических страниц, JavaScript стал делать реальную работу прямо в браузере, и проверять такое «глазами по чеклисту» стало невозможно. Автоматизированные инструменты тогда были — но коммерческие, дорогие и проприетарные.

Статус на сегодня: живой проект, лицензия Apache 2.0, четвёртая ветка активно развивается, юридический владелец — Software Freedom Conservancy. Джейсон Хаггинс в 2008 году стал сооснователем Sauce Labs — компании, продающей Selenium-инфраструктуру как облачный сервис.

Что это такое

Selenium — это не одна программа, а зонтичный бренд над несколькими вещами, и путаница между ними — источник половины недоразумений.

Selenium WebDriver — то, что обычно имеют в виду. Это библиотека для твоего языка (Python, Java, C#, JavaScript, Ruby и другие) плюс протокол общения с браузером. Ты пишешь driver.find_element(...) и .click(), библиотека превращает это в HTTP-запрос, драйвер принимает запрос и дёргает браузер за внутренние рычаги.

Selenium Grid — сервер-диспетчер. Ты отправляешь ему задачу «прогони этот сценарий в Chrome под Windows», он находит свободную машину с нужной комбинацией и выполняет. Нужен, когда тестов сотни и прогонять их последовательно на одном ноутбуке — это полночи.

Selenium IDE — расширение для браузера, записывающее действия. Годится для быстрых демонстраций и людей без кода, но серьёзные сценарии на нём не строят: записанные шаги ломаются от любой перестановки вёрстки.

Ключевое отличие от всего остального класса инструментов: Selenium управляет настоящим браузером, а не имитирует его. Разберём явные пары.

Selenium vs requests/curl. Библиотека HTTP-запросов забирает у сервера исходный HTML и на этом останавливается. Если страница рисуется JavaScript-ом уже в браузере (а так работает большинство современных интерфейсов), в исходном HTML не будет ничего, кроме пустого контейнера. Selenium дожидается, пока браузер всё отрисует, и видит итог. Плата — скорость: HTTP-запрос это десятки миллисекунд, запуск браузера — секунды.

Selenium vs headless-браузер. Это не альтернативы: headless (безголовый) — это режим запуска браузера без видимого окна, и Selenium прекрасно умеет и так, и так. Видимое окно нужно, когда надо посмотреть глазами или когда сайт подозрительно относится к headless-режиму.

Selenium vs парсер HTML (BeautifulSoup, lxml). Парсер разбирает уже полученный текст. Selenium — добывает этот текст из живой страницы. Их часто используют вместе: Selenium открыл и дождался, парсер разобрал.

Selenium vs макрос-кликер (AutoHotkey и подобные). Кликер двигает реальный курсор по координатам экрана и слеп к содержимому: сдвинулась вёрстка — промазал. Selenium адресуется к элементам по их идентификаторам в DOM (объектной модели документа), а не по пикселям.

Аналогии из жизни

Пульт дистанционного управления телевизором. Ты не лезешь внутрь телевизора паяльником, не эмулируешь его схему — ты пользуешься теми кнопками, которые производитель сам вывел наружу. Selenium ровно так: не подделывает браузер, а нажимает на штатные ручки управления, которые Google и Mozilla сами вынесли для автоматизации.

Где ломается: у пульта конечный набор кнопок, и все они существуют ради человека. У браузера же есть вещи, которые человеку не нужны, а автоматизации — очень: перехватить сетевой запрос, подменить заголовок, посмотреть таймлайн загрузки. Штатный WebDriver-протокол их долго не покрывал, поэтому Selenium 4 отдельным ходом пристегнул Chrome DevTools Protocol — «сервисный разъём», которого у бытового пульта нет.

Автоинструктор с дублирующими педалями. В учебной машине второй комплект педалей идёт к тому же приводу, что и основной. Машина не различает, кто нажал. Так же и браузер: клик от Selenium проходит по тем же внутренним путям, что и клик человека, — срабатывают те же обработчики событий, отправляются те же запросы.

Где ломается: инструктор всё-таки сидит внутри машины и видит дорогу. Selenium «видит» только то, что доступно через протокол: текст, атрибуты, размеры, координаты элементов. Он не воспринимает страницу визуально. Кнопка, целиком закрытая всплывающим баннером, для него часто выглядит совершенно нормальной, и клик уходит в баннер. Отсюда классическая ошибка ElementClickInterceptedException — «в элемент кликнули, но перехватил другой».

Дирижёр и оркестр через посредника. Представь, что дирижёр не стоит перед оркестром, а передаёт указания через ассистента: «вторая скрипка, вступай». Ассистент знает, кто где сидит, и переводит команду конкретному музыканту. Ассистент — это драйвер (chromedriver), оркестр — браузер.

Где ломается: у настоящего дирижёра есть слух, и он реагирует мгновенно, если что-то пошло не так. У Selenium обратная связь дискретная: он спрашивает состояние страницы отдельными запросами. Между «спросил» и «получил ответ» страница могла измениться. Вся проблематика ожиданий (wait) в Selenium растёт именно из этого разрыва — самый частый источник «плавающих» тестов, которые проходят через раз.

Главная ловушка новичка

Первый написанный на Selenium скрипт почти всегда падает не там, где ожидаешь: элемент «ещё не появился». Соблазн — воткнуть time.sleep(5). Это работает на твоей машине и разваливается на медленном сервере. Правильный путь — явные ожидания (WebDriverWait с условием): ждать не «пять секунд», а «пока кнопка не станет кликабельной, но не дольше тридцати секунд».

Как это работает

Между твоим кодом и браузером выстраивается цепочка из четырёх звеньев:

Твой скрипт  →  Selenium-библиотека  →  HTTP  →  Драйвер  →  Браузер
 (Python)       (клиентские bindings)           (chromedriver)  (Chrome)

Пошагово, что происходит, когда ты запускаешь скрипт:

1. Старт сессии. Библиотека поднимает процесс драйвера — отдельный исполняемый файл (chromedriver, geckodriver), который слушает локальный порт. Потом шлёт ему POST-запрос «новая сессия» с описанием желаемого браузера — набор параметров называется capabilities (возможности): какой браузер, какая версия, headless или нет, какой профиль пользователя, какие флаги запуска. Драйвер запускает браузер и возвращает sessionId — идентификатор, который дальше приклеивается ко всем командам.

2. Команды — это HTTP-запросы. Каждое действие в твоём коде превращается в отдельный HTTP-вызов к драйверу по адресу вида /session/<id>/element с телом в JSON. Это и есть суть протокола W3C WebDriver: он синхронный, текстовый и до неприличия простой. find_element — один запрос, click — второй, get_text — третий. Именно поэтому Selenium медленнее инструментов, работающих через постоянное соединение: на каждый чих — полный цикл «запрос-ответ», пусть и по локальной сети.

3. Поиск элемента. Ты описываешь, что искать, — это называется локатор. Основные виды: по id, по CSS-селектору, по XPath (язык адресации узлов в дереве документа), по тексту ссылки. Драйвер выполняет поиск в DOM и возвращает не сам элемент, а ссылку на него — непрозрачный идентификатор. Если страница успела перерисоваться, ссылка протухает, и следующая операция падает с StaleElementReferenceException («ссылка на устаревший элемент»).

4. Действие. Клик, ввод текста, прокрутка. Драйвер не рисует движение мыши — он генерирует события ввода на уровне браузера, так что страница не отличает их от человеческих. Перед кликом драйвер по стандарту проверяет, что элемент видим и не перекрыт; не прошло проверку — ошибка вместо тихого промаха.

5. Ожидания. Три уровня. Неявное (implicit wait) — глобальное «если элемента нет, поищи ещё N секунд». Явное (WebDriverWait + условие) — «жди конкретно этого состояния», единственный по-настоящему надёжный способ. И sleep — то, чего делать не надо.

6. Завершение. driver.quit() закрывает сессию, гасит браузер и убивает драйвер. Если этого не сделать — процессы браузера остаются висеть и копиться. Живой пример из практики: если оставить Chrome открытым на каком-то профиле, следующий запуск Selenium с тем же профилем упадёт — профиль занят блокировкой, и два процесса в него не помещаются.

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

Где встречается в обычной жизни

Где встречается в IT и бизнесе

Почему стандартизация важнее самого Selenium

Настоящий результат проекта — не библиотека, а протокол W3C WebDriver. Selenium сделал управление браузером частью веб-стандарта, и теперь любой инструмент может говорить с любым браузером на одном языке. Даже если Selenium однажды уступит место конкурентам, стандарт, который он породил, останется — примерно как HTTP пережил браузер Mosaic.

Кто пользуется

Selenium — один из самых распространённых инструментов в индустрии тестирования; по опросам разработчиков он много лет держится в верхней части списков инструментов автоматизации веб-тестирования. Точных долей называть не буду — цифры в таких опросах гуляют.

Конкретные потребители:

Масштабы Selenium Grid в больших компаниях — сотни параллельных браузеров, прогон полного набора тестов за минуты вместо ночи.

Альтернативы и конкуренты

Playwright (Microsoft, 2020; делала команда, ранее создавшая Puppeteer в Google).
Плюсы: заметно быстрее, встроенные умные ожидания (сам ждёт готовности элемента), из коробки перехват сети, эмуляция устройств, параллельные изолированные контексты, отличная отладка.
Минусы: младше, а значит меньше накопленных решений на все случаи; работает через собственные протоколы, а не только через W3C-стандарт; поддержка Safari — через сборку WebKit, а не системный браузер.

Puppeteer (Google, 2017).
Плюсы: очень быстрый, прямой доступ к Chrome DevTools Protocol, идеален для генерации PDF и скриншотов.
Минусы: по сути только Chrome/Chromium; исторически только JavaScript.

Cypress (2017).
Плюсы: исполняется внутри браузера рядом с приложением, поэтому даёт лучший в классе опыт отладки — видно каждый шаг с состоянием страницы.
Минусы: архитектура «изнутри страницы» накладывает ограничения (работа с несколькими вкладками и доменами исторически болезненна), только JavaScript/TypeScript, часть возможностей — в платной версии.

Прямые HTTP-запросы (requests, httpx, curl).
Плюсы: на порядки быстрее и дешевле, никакого браузера, легко ставится на сервер.
Минусы: не работает там, где контент рисуется JavaScript-ом, и требует разобраться во внутренних запросах сайта, которые могут поменяться без предупреждения.

Когда НЕ стоит использовать

Когда у сервиса есть API. Если данные можно получить HTTP-запросом к документированной ручке — браузер здесь чистые накладные расходы: медленнее в десятки раз, ломается от любой перерисовки вёрстки, требует установленного Chrome на сервере. Потому что автоматизация интерфейса — это всегда обход отсутствия нормального интерфейса для машин.

Когда нужна проверка бизнес-логики, а не интерфейса. Гонять браузер, чтобы проверить формулу расчёта скидки, — дорого и медленно. Такие вещи проверяются юнит-тестами за миллисекунды. Потому что чем выше уровень теста, тем он дороже и хрупче: пирамида тестирования не зря нарисована именно в таком порядке.

Когда сценарий — разовый и простой. Один раз выгрузить отчёт быстрее руками, чем полдня писать и отлаживать скрипт. Потому что автоматизация окупается только на повторяемости.

Когда целевой сайт прямо запрещает автоматический доступ. Условия использования и robots.txt — не техническая, а юридическая и репутационная граница. Технически обойти можно почти всё; вопрос в том, что будет, когда заметят.

Связанные понятия

Литература и источники

Где встретилось у меня

Вчера разбирался с агентом, который ходит в рекламный кабинет CRM через офисный VPN: Selenium держит видимое залогиненное окно Chrome на отдельном профиле, а дальше данные качаются обычными HTTP-запросами по cookies, снятым из этой же сессии. Всплыли ровно те грабли, о которых написано выше: профиль браузера — монопольный ресурс, и пока живёт одно окно, второй драйвер в него не зайдёт. Отдельно пригодился performance-лог драйвера — через него удалось составить инвентарь внутренних запросов кабинета и перевести часть сбора с медленного разбора страницы на быстрые прямые вызовы.

Краткое резюме