Selenium
Selenium
Selenium — набор инструментов, который позволяет программе управлять настоящим браузером: открывать страницы, кликать, вводить текст, читать содержимое. В основе лежит WebDriver — стандартизированный протокол, по которому твой код на Python, Java или JavaScript отдаёт браузеру команды через промежуточный драйвер.
История
Selenium родился из бытовой боли тестировщиков начала 2000-х. Веб-приложения перестали быть набором статических страниц, JavaScript стал делать реальную работу прямо в браузере, и проверять такое «глазами по чеклисту» стало невозможно. Автоматизированные инструменты тогда были — но коммерческие, дорогие и проприетарные.
- 2004, Чикаго, США. Джейсон Хаггинс (Jason Huggins), инженер консалтинговой компании ThoughtWorks, пишет для внутреннего проекта библиотеку на JavaScript, которую называет JavaScriptTestRunner. Идея простая: если JavaScript уже выполняется внутри страницы, то он же может и кликать по элементам этой страницы. Позже эта штука станет известна как Selenium Core.
- Откуда название. Главным коммерческим конкурентом тогда был Mercury Interactive с продуктом QuickTest Professional. Mercury по-английски — ещё и «ртуть». Хаггинс пошутил в рассылке, что от отравления ртутью помогает селен (selenium), — шутка прижилась и стала именем проекта. Это, кстати, редкий случай, когда происхождение названия инструмента задокументировано самим автором, а не додумано потом.
- ~2005, Selenium RC. У подхода «JavaScript внутри страницы» обнаружился фундаментальный потолок: same-origin policy (политика одного источника) — браузер запрещает скрипту с одного домена лезть в содержимое другого. Пол Хаммант (Paul Hammant), тоже из ThoughtWorks, предложил обходной манёвр: поставить между тестом и браузером HTTP-прокси-сервер, который выдаёт тестовый JavaScript как будто с того же домена. Так появился Selenium Remote Control (RC), он же Selenium 1. Он работал, но был медленным и хрупким — прокси врал браузеру, и браузер иногда это замечал.
- ~2006, WebDriver. Саймон Стюарт (Simon Stewart), тогда тоже в ThoughtWorks, начал независимый проект WebDriver с принципиально другой идеей: не подсовывать браузеру скрипты снаружи, а управлять им «изнутри», через его собственные механизмы автоматизации — то, что сегодня в каждом браузере есть штатно. Никакого прокси, никакого обмана.
- 2006, Selenium IDE. Японский разработчик Синъя Касатани (Shinya Kasatani) написал плагин для Firefox, который умел записывать действия пользователя и воспроизводить их. Он передал его проекту Selenium — так у инструмента появилось «записал и проиграл» для тех, кто не пишет код.
- 2009 — слияние. Два проекта решили объединиться: Selenium дал сообщество и экосистему, WebDriver — правильную архитектуру. Результатом стал Selenium 2.0 (релиз — 2011), где WebDriver стал главным API, а старый RC оставили для совместимости.
- Октябрь 2016 — Selenium 3.0. Selenium Core и RC окончательно выброшены. Управление идёт только через нативные драйверы браузеров:
chromedriverот команды Chromium,geckodriverот Mozilla, свои — у Safari и Edge. Тогда же проект перешёл под крыло Software Freedom Conservancy (некоммерческая организация, держащая юридическую оболочку для open-source проектов). - Июнь 2018 — W3C WebDriver. Протокол, выросший из Selenium, стал официальной рекомендацией W3C. Это ключевой момент: с этого дня «управление браузером» — не фича одной библиотеки, а веб-стандарт, который производители браузеров обязаны поддерживать наравне с HTML и CSS.
- Октябрь 2021 — Selenium 4.0. Полный переход на W3C-протокол (старый JSON Wire Protocol удалён), переписанный Grid, поддержка Chrome DevTools Protocol для низкоуровневых вещей вроде перехвата сетевых запросов.
- 2022 и дальше. В ветке 4.6 появился Selenium Manager — он сам скачивает нужную версию драйвера под установленный браузер. До этого вечной болью было «обновился Chrome — сломался chromedriver».
Статус на сегодня: живой проект, лицензия 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 (куки), сохранённые сессии и расширения. Это превращает «залогиниться заново каждый запуск» в «мы уже вошли». Побочный эффект тот же: профиль — монопольный ресурс.
Где встречается в обычной жизни
- Ты сдаёшь показания счётчиков или бронируешь слот на сайте госуслуг, и там всё «живое». Перед релизом такого сайта кто-то прогнал сотни автоматических сценариев, кликающих по тем же кнопкам, что и ты. Значительная часть — на Selenium.
- Агрегаторы цен и авиабилетов. Часть источников отдаёт данные по API, часть — только через сайт. Второе собирают именно браузерной автоматизацией.
- «Робот» в личном кабинете банка или маркетплейса. Когда какой-то сервис показывает тебе данные из другого сервиса, у которого нет публичного API, за этим часто стоит браузер-автомат, заходящий под твоими или корпоративными доступами.
- Мониторинг доступности сайтов. Сервисы, которые каждые пять минут проверяют не «отвечает ли сервер», а «открывается ли страница и работает ли кнопка», запускают для этого настоящие браузеры.
- Массовые проверки вёрстки. Скриншоты одной страницы в двадцати разрешениях и трёх браузерах, которые дизайнер получает пачкой, — делаются скриптом, а не руками.
Где встречается в IT и бизнесе
- Регрессионное тестирование. Классика и главный сценарий: после каждого изменения кода автоматически проверить, что сто ранее работавших сценариев не сломались. Без этого любой релиз — лотерея.
- RPA (Robotic Process Automation, роботизация процессов). Легаси-система без API, но с веб-интерфейсом — и есть ежедневная рутина «зайти, выгрузить отчёт, переложить в таблицу». Браузерная автоматизация закрывает это без интеграции, за которую вендор попросит полугодовой бюджет.
- Сбор данных (скрейпинг). Конкурентная разведка, мониторинг цен, выгрузка собственных данных из чужой CRM. Частый гибридный приём: Selenium проходит логин и забирает cookies, а дальше данные качаются быстрыми HTTP-запросами с этими cookies — браузер нужен только на трудный участок.
- Кроссбраузерные проверки. Один сценарий, прогнанный в Chrome, Firefox, Safari и Edge, находит различия рендеринга до того, как их найдёт клиент.
- Синтетический мониторинг. Не «сервер жив», а «пользовательский путь от главной до оплаты проходится за N секунд». Метрика, понятная бизнесу, а не только админу.
Почему стандартизация важнее самого Selenium
Настоящий результат проекта — не библиотека, а протокол W3C WebDriver. Selenium сделал управление браузером частью веб-стандарта, и теперь любой инструмент может говорить с любым браузером на одном языке. Даже если Selenium однажды уступит место конкурентам, стандарт, который он породил, останется — примерно как HTTP пережил браузер Mosaic.
Кто пользуется
Selenium — один из самых распространённых инструментов в индустрии тестирования; по опросам разработчиков он много лет держится в верхней части списков инструментов автоматизации веб-тестирования. Точных долей называть не буду — цифры в таких опросах гуляют.
Конкретные потребители:
- Крупные продуктовые компании — практически все, у кого есть веб-интерфейс и релизы чаще раза в месяц. Selenium используется внутри Google, Microsoft, Netflix и множества других — во многом потому, что появился задолго до конкурентов и успел врасти в инфраструктуру.
- Sauce Labs (основана в 2008, сооснователь — автор Selenium Джейсон Хаггинс) — облачная ферма браузеров: ты шлёшь тест, они прогоняют его на нужной комбинации ОС и браузера.
- BrowserStack (Индия, основана в 2011) и LambdaTest — прямые конкуренты в том же сегменте, предоставляют доступ к тысячам комбинаций браузер/ОС/устройство.
- Банки и телеком — там, где тестируют старые внутренние порталы, которые никто не переписывает, но которые должны работать.
- Аналитические и маркетинговые команды — там, где надо выгружать данные из рекламных и CRM-кабинетов, не имеющих открытого API.
Масштабы 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 — не техническая, а юридическая и репутационная граница. Технически обойти можно почти всё; вопрос в том, что будет, когда заметят.
Связанные понятия
- WebDriver (W3C) — стандартизированный HTTP+JSON-протокол управления браузером; технический фундамент современного Selenium.
- DOM (Document Object Model) — дерево объектов, в которое браузер превращает HTML-страницу; именно в нём Selenium ищет элементы.
- CSS-селектор и XPath — два языка адресации узлов в DOM; первый короче и быстрее, второй мощнее (умеет искать по тексту и подниматься к родителю).
- Headless-браузер — режим работы браузера без видимого окна; экономит ресурсы, но легче детектируется защитами.
- Chrome DevTools Protocol (CDP) — низкоуровневый протокол Chromium для отладки и перехвата сетевого трафика; то, чего нет в стандартном WebDriver.
- Same-origin policy — запрет браузера на доступ скрипта к данным чужого домена; именно она в 2005-м похоронила архитектуру Selenium Core.
- Flaky-тест — тест, который проходит через раз без изменений в коде; главная болезнь браузерной автоматизации, обычно от неправильных ожиданий.
Литература и источники
- Официальная документация Selenium —
selenium.dev/documentation(en, есть частичный перевод на русский). Основной и самый актуальный источник. - Спецификация W3C WebDriver —
w3.org/TR/webdriver2/(en). Читается тяжело, но это первоисточник: там описан каждый эндпоинт протокола. - Wikipedia: Selenium (software) —
en.wikipedia.org/wiki/Selenium_(software)(en). Хорошая сводка по истории и версиям. - Selenium WebDriver 3 Practical Guide, Boni Garcia (en) — практическое введение; у Гарсии же есть более свежие материалы по четвёртой ветке.
- Блог Пола Хамманта (paulhammant.com) — воспоминания одного из ранних авторов о том, как появлялись Selenium RC и WebDriver. Первоисточник по истории проекта.
- Для сравнения с конкурентами — официальная документация Playwright (
playwright.dev) и Cypress (docs.cypress.io); искать в поиске по запросу «Selenium vs Playwright architecture comparison».
Где встретилось у меня
Вчера разбирался с агентом, который ходит в рекламный кабинет CRM через офисный VPN: Selenium держит видимое залогиненное окно Chrome на отдельном профиле, а дальше данные качаются обычными HTTP-запросами по cookies, снятым из этой же сессии. Всплыли ровно те грабли, о которых написано выше: профиль браузера — монопольный ресурс, и пока живёт одно окно, второй драйвер в него не зайдёт. Отдельно пригодился performance-лог драйвера — через него удалось составить инвентарь внутренних запросов кабинета и перевести часть сбора с медленного разбора страницы на быстрые прямые вызовы.
Краткое резюме
- Selenium управляет настоящим браузером через отдельный драйвер по протоколу W3C WebDriver — не имитирует, а нажимает на штатные рычаги.
- Придуман в 2004-м Джейсоном Хаггинсом в ThoughtWorks; название — шутка про «селен против отравления ртутью» (Mercury Interactive).
- Главное наследие проекта — не библиотека, а стандарт: с 2018 года WebDriver — рекомендация W3C, и его поддерживают все браузеры.
- Плата за реалистичность — скорость и хрупкость: каждая команда это отдельный HTTP-запрос, а половина проблем растёт из ожиданий («элемент ещё не появился»).
- Есть API — используй API. Браузерная автоматизация оправдана там, где машинного интерфейса нет: тестирование UI, RPA над легаси-системами, сбор данных из кабинетов без API.