Selenium и Playwright в Python: как выбрать без переделок
Оба инструмента автоматизируют браузер, но платите за них по-разному: скоростью тестов, стабильностью на динамике и временем на настройку. Разбираем, когда какой брать, чтобы не переписывать проект через месяц.

Задача звучит просто: открыть страницу, дождаться загрузки данных, кликнуть кнопку, забрать результат. На статическом HTML это делает requests плюс BeautifulSoup. Но если контент подгружается JavaScript'ом после первого рендера, а на странице капча-виджеты и ленивая подгрузка — без реального браузера не обойтись. Тут начинается выбор между Selenium и Playwright, и цена ошибки — не в первый день, а на второй сотне тестов, когда половина падает по таймауту.
Здесь разбираем именно выбор и типичные грабли на старте для Python. Версии, о которых речь: Selenium 4.x и Playwright для Python 1.4x. Селекторы, паттерны страниц (Page Object) и параллельный запуск в CI — смежные темы, их не разворачиваем.
Почему очевидное решение подводит
Очевидное решение для новичка — взять Selenium: он старше, туториалов больше, на любой вопрос есть ответ. Проблема всплывает не сразу. Selenium исторически требует отдельного драйвера под каждый браузер (ChromeDriver, GeckoDriver), и версия драйвера должна совпадать с версией браузера. Обновился Chrome — тест упал с SessionNotCreatedException. С Selenium 4.6+ появился Selenium Manager, который скачивает драйвер сам, но про него знают не все, и статьи двухлетней давности всё ещё учат вручную качать chromedriver.exe.
Вторая боль — ожидания. В браузере элемент появляется не мгновенно. Наивный код driver.find_element(...) сразу после загрузки страницы падает с NoSuchElementException, потому что данные ещё летят по сети. Новичок лепит time.sleep(3), тест становится медленным и всё равно иногда падает.
Playwright с этими двумя проблемами родился без болезней: он ставит браузеры одной командой и по умолчанию ждёт элемент перед действием (auto-waiting). Но и у него есть цена — об этом ниже.
Два подхода: чем платите за каждый
Selenium 4.x
Зрелая экосистема, работает почти со всем, огромное сообщество, привязок под языки больше, чем у любого конкурента. Grid для распределённого запуска — проверенный временем. Платите за это ручной работой с ожиданиями (нужно осознанно использовать WebDriverWait и expected_conditions) и тем, что API синхронный по своей природе — асинхронность прикручивается сбоку.
Playwright 1.4x
Один пакет ставит Chromium, Firefox и WebKit. Auto-waiting из коробки: перед кликом библиотека сама проверяет, что элемент видим, включён и не перекрыт. Есть и синхронный, и асинхронный API. Встроенные перехват сети, эмуляция устройств, запись трейсов для отладки. Платите за это тем, что экосистема моложе — на редкий вопрос ответ найдётся не всегда, а часть корпоративных инструментов заточена под Selenium.
| Критерий | Selenium 4.x | Playwright 1.4x |
|---|---|---|
| Установка браузеров | Selenium Manager (4.6+) или вручную | playwright install |
| Ожидание элементов | Ручное: WebDriverWait | Автоматическое перед действием |
| Async из коробки | Нет (только sync) | Да (sync и async API) |
| Перехват сети | Через CDP, сложнее | Встроенный page.route |
| Возраст и объём сообщества | Больше, старше | Меньше, растёт |
| Отладка | Скриншоты, логи | Трейсы, Inspector, codegen |
Установка и первый рабочий скрипт
Начинать чистый проект в 2024–2025 году разумнее с Playwright. Установка:
pip install playwright
playwright install chromiumПервая команда ставит Python-пакет, вторая скачивает браузер. Без второй команды скрипт упадёт с сообщением, что браузер не найден.
Минимальный рабочий скрипт на синхронном API — открыть страницу, дождаться заголовка, забрать текст:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
# headless=False покажет окно браузера, удобно для отладки
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com")
# goto по умолчанию ждёт события load
heading = page.locator("h1").inner_text()
print(heading)
browser.close()Обратите внимание: явного ожидания h1 нет, а падения по таймауту тоже нет. locator(...).inner_text() сам дождётся появления элемента до дефолтного таймаута (30 секунд). Это и есть auto-waiting.
Тот же результат на Selenium 4.x требует явного ожидания:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Selenium Manager сам подберёт драйвер под установленный Chrome
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
# ждём максимум 10 секунд появления h1
heading = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h1"))
)
print(heading.text)
finally:
driver.quit()Разница в объёме кода наглядна: на Selenium вы сами отвечаете за ожидание каждого динамического элемента. Забыли WebDriverWait — получили флейки (тесты, которые падают через раз).
Главная причина нестабильных браузерных тестов — не выбор библиотеки, а time.sleep вместо явного ожидания условия. Playwright прячет эту проблему по умолчанию, Selenium требует держать её в голове.Локаторы: где ломаются оба
Самая частая ошибка на старте — привязка к хрупким селекторам. XPath вида /html/body/div[3]/div[2]/button сломается при первом же изменении вёрстки. Это не проблема библиотеки, а проблема стратегии, и она общая для Selenium и Playwright.
Playwright предлагает локаторы по видимой роли и тексту, которые ближе к тому, что видит пользователь:
# устойчивее к рефакторингу вёрстки
page.get_by_role("button", name="Войти").click()
page.get_by_label("Электронная почта").fill("user@example.com")В Selenium аналога get_by_role из коробки нет — там опираются на By.CSS_SELECTOR и осмысленные атрибуты вроде data-testid. Если фронтенд под вашим контролем, договоритесь с командой добавлять data-testid на ключевые элементы — это снимает большую часть боли с обоими инструментами.
Если не получилось
- Playwright:
Executable doesn't exist at ...— не выполнена командаplaywright install chromium. Запустите её послеpip install. - Selenium:
SessionNotCreatedException: This version of ChromeDriver only supports Chrome version N— драйвер не совпадает с браузером. На Selenium 4.6+ удалите ручной драйвер из PATH и дайте работать Selenium Manager. - Playwright:
TimeoutError: waiting for locator ...— селектор не находит элемент за 30 секунд. Либо селектор неверный, либо элемент внутри iframe (нуженpage.frame_locator), либо страница вообще не догрузилась. Запустите сheadless=Falseи посмотрите глазами. - Оба: тест падает в CI, но проходит локально — почти всегда разница в таймингах и в headless-режиме. В CI ставьте headless явно и увеличивайте таймауты, а не добавляйте
sleep. - Selenium:
ElementClickInterceptedException— элемент перекрыт другим (баннер, оверлей). Дождитесь исчезновения перекрывающего элемента черезWebDriverWait, а не кликайте вслепую.
Когда что выбирать
- Новый проект без легаси — Playwright. Меньше кода на ожидания, встроенная отладка, один пакет для всех браузеров.
- Проект уже на Selenium — не переписывайте ради моды. Обновитесь до Selenium 4.x, включите Selenium Manager, наведите порядок с
WebDriverWait. - Нужен браузер, которого нет у Playwright (например, специфичная сборка) или интеграция с корпоративным Grid — Selenium.
- Тяжёлый перехват и подмена сетевых запросов, эмуляция устройств, мобильные вьюпорты — Playwright, здесь у него всё встроено.
Что делать дальше
Как только первый скрипт заработал, не оставляйте код в виде плоского списка команд. Следующий шаг — вынести селекторы и действия страницы в отдельный класс (Page Object), чтобы при смене вёрстки править одно место. Дальше — подключить запуск в CI headless и настроить трейсы Playwright или скриншоты Selenium при падении, иначе отладка упавшего в пайплайне теста превращается в гадание. И заведите привычку: любой новый sleep в коде — повод остановиться и заменить его на явное ожидание условия.
Тест и проверочная: Быстрые ответы с объяснением, почему остальные варианты неверны
Спросить за 10 ₽Источники: Playwright for Python — официальная документация, Selenium — официальная документация
Частые вопросы
У меня уже проект на Selenium 3, стоит ли переходить на Playwright?
Что делать, если у меня другая версия Playwright или Selenium?
Скрипт падает по таймауту, хотя элемент на странице есть — почему?
Можно ли обойтись без реального браузера?
Почему тесты проходят локально, но падают в CI?
Какие подводные камни ждут в проде при большом числе браузеров?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.