В современном мире веб-разработки и автоматизации Playwright стал незаменимым инструментом для тестирования, скрейпинга и автоматизации браузеров. Этот мощный фреймворк произвел революцию в том, как мы взаимодействуем с веб-приложениями программным путем.
Что такое Playwright?
Playwright – это мощная библиотека автоматизации браузера, разработанная Microsoft, которая позволяет контролировать браузеры через единый мощный API. Представьте себе универсальный пульт управления, который работает с любым браузером и позволяет:
- Автоматизировать тестирование веб-приложений
- Собирать данные (в простонароде — писать парсеры) с веб-сайтов (веб-скрейпинг и парсинг данных)
- Создавать скриншоты и PDF-файлы
- Эмулировать мобильные устройства
- Автоматизировать рутинные задачи в браузере
В его основе лежит Node.js движок, но благодаря официальным привязкам он доступен для Python, Java и .NET. Фреймворк родился из опыта команды, ранее создавшей Puppeteer, что позволило учесть все недостатки существующих решений и создать по-настоящему надёжный инструмент автоматизации. В отличие от Selenium, который использует WebDriver API, Playwright напрямую управляет браузером через CDP (Chrome DevTools Protocol) для Chromium-based браузеров и специальные протоколы для Firefox и WebKit. Это даёт несколько критических преимуществ: более быстрое и стабильное выполнение команд, точный контроль над браузером, расширенные возможности автоматизации, нативная поддержка современных веб-технологий.
История создания
Playwright появился в январе 2020 года, когда команда разработчиков Puppeteer перешла из Google в Microsoft. Они поставили перед собой амбициозную задачу – создать инструмент нового поколения, который решит основные проблемы существующих решений для автоматизации браузеров.
Почему Playwright стал популярным и массвого используется с начала 2024 года?
Кроссбраузерность из коробки
- Работает с Chromium (включая Chrome, Edge, Opera) – самыми популярными браузерами для обычных пользователей
- Поддерживает Firefox – для тестирования на альтернативном движке
- Работает с WebKit (Safari) – критично для проверки на устройствах Apple
- Один и тот же код работает во всех браузерах без изменений
Современная архитектура
- Автоматически ждёт загрузки элементов (не нужно писать time.sleep или явные ожидания)
- Каждый тест запускается в чистом окружении (как будто вы открыли браузер в первый раз)
- Отлично работает с Single Page Applications (React, Vue, Angular)
- Поддерживает работу с несколькими вкладками и окнами одновременно
Надёжность и стабильность
- Тесты стабильно проходят без случайных сбоев
- Автоматически перезапускает упавшие тесты
- Детальные отчёты об ошибках с скриншотами и видео
- Работает одинаково в Windows, Mac и Linux
Удобство для парсинга
- Легко обходит защиту от ботов (капчи, JavaScript-проверки)
- Может эмулировать реальный браузер пользователя
- Поддерживает работу через прокси
- Умеет сохранять и загружать cookies
Пример базового использования на Python:
from playwright.sync_api import sync_playwright
def run(playwright):
# Запускаем браузер
browser = playwright.chromium.launch(headless=False)
# Создаём новую страницу
page = browser.new_page()
# Переходим на сайт
page.goto("https://example.com")
# Ждём и кликаем по кнопке (автоматическое ожидание)
page.click("text=Принять")
# Заполняем форму
page.fill("input[name='search']", "ноутбук")
# Делаем скриншот
page.screenshot(path="screenshot.png")
browser.close()
with sync_playwright() as playwright:
run(playwright)
Области применения
-
UI-тесты: проверка работы интерфейса вашего сайта
def test_login_form(): page.fill("input[name='username']", "user@example.com") page.fill("input[name='password']", "password123") page.click("button:has-text('Войти')") assert page.is_visible("text=Личный кабинет")
-
Проверка вёрстки: как сайт выглядит на разных устройствах
-
Тестирование производительности: замер скорости загрузки страниц
-
Мониторинг цен: отслеживание стоимости товаров у конкурентов
def get_product_prices(): prices = page.query_selector_all(".price") return [price.inner_text() for price in prices]
-
Автоматический сбор контактов, например, email-адресов и телефонов для последующего прогрева клиентов (частая фишка маркетинга с последующими прозвонами).
-
Агрегация новостей, где необходимо собирать новости с разных сайтов
-
Анализ конкурентов, за счёт мониторинга акций и специальных предложений
- Автоматическое заполнение форм, например, для регистрации аккаунтов
- Автоматическое создание PDF с данными для генерации отчётов
- Мониторинг доступности, где проверяется работоспособность сайтов
- Автоматизация рутины, например, выгрузка данных из личных кабинетов
- Проверка SEO-параметров: анализ метатегов, заголовков, описаний
- Мониторинг позиций: отслеживание положения в поисковой выдаче
- Анализ контента: проверка уникальности и качества текстов
- Сбор семантики: анализ ключевых слов конкурентов
from playwright.sync_api import sync_playwright
def analyze_seo(url):
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto(url)
seo_data = {
"title": page.title(),
"description": page.query_selector('meta[name="description"]').get_attribute('content'),
"h1": page.query_selector('h1').inner_text(),
"links": len(page.query_selector_all('a')),
}
browser.close()
return seo_data
# Использование
results = analyze_seo("https://example.com")
print(results)
Каждая из этих областей открывает широкие возможности для автоматизации и оптимизации бизнес-процессов, экономя время и ресурсы компании.
Основные преимущества Playwright
Сравнение с конкурентами
Характеристика | Playwright | Selenium | Cypress |
---|---|---|---|
Скорость работы | Очень высокая | Средняя | Высокая |
Кроссбраузерность | Chrome, Firefox, Safari | Все браузеры | Только Chrome |
Параллельное выполнение | Встроенное | Требует настройки | Платная версия |
Работа с Shadow DOM | Нативная поддержка | Ограниченная | Хорошая |
API для работы | Современный | Устаревший | Современный |
Как отмечалось выше, Playwright построен на основе Node.js и имеют свою реализацию работы с браузерами, и не является обёрткой над Selenium, как большинство других решений.
-
Умное ожидание элементов. Playwright имеет встроенную систему автоматического ожидания элементов с настраиваемыми таймаутами для различных операций.
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() # Автоматически дождётся появления кнопки page.click("button#submit") # В Selenium пришлось бы писать: # WebDriverWait(driver, 10).until( # EC.element_to_be_clickable((By.ID, "submit")) # ) browser.close()
Основные методы ожидания и их таймауты.
from playwright.sync_api import sync_playwright with sync_playwright() as p: # Глобальные настройки таймаутов при создании браузера browser = p.chromium.launch() page = browser.new_page(no_viewport=True) page.set_default_timeout(3 * 60000) # Глобальный таймаут в миллисекундах page.set_default_navigation_timeout(3 * 60000) # Глобальный таймаут в миллисекундах # Пример с различными таймаутами try: # Ожидание появления элемента (по умолчанию 30 секунд) page.wait_for_selector("button#submit") # Переопределение таймаута для конкретного действия page.click("button#submit", timeout=5000) # 5 секунд # Ожидание загрузки страницы page.wait_for_load_state("networkidle", timeout=10000) # 10 секунд # Ожидание исчезновения элемента page.wait_for_selector(".loader", state="hidden", timeout=15000) # 15 секунд except TimeoutError: print("Элемент не появился в указанное время") # Дополнительные примеры # Ожидание появления элемента с определенным состоянием page.wait_for_selector("button#submit", state="visible", # visible, hidden, attached, detached timeout=5000, # Таймаут в миллисекундах strict=True # Строгий режим - ошибка при нескольких элементах ) # Ожидание изменения URL page.wait_for_url("https://example.com/success", timeout=10000, wait_until="networkidle" # load, domcontentloaded, networkidle ) # Ожидание определенного состояния страницы page.wait_for_load_state( state="networkidle", # load, domcontentloaded, networkidle timeout=15000 ) # Ожидание выполнения JavaScript условия page.wait_for_function(""" () => document.querySelector('.data')?.textContent.includes('Ready') """, timeout=20000)
-
Мощная изоляция тестов
# Каждый контекст изолирован async def test_isolation(): context1 = browser.new_context() context2 = browser.new_context() page1 = context1.new_page() page2 = context2.new_page() # Cookies и localStorage не пересекаются await page1.add_cookie({"name": "test", "value": "1"}) await page2.add_cookie({"name": "test", "value": "2"})
-
Работа с сетью
# Перехват и модификация запросов page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort()) # Блокировка картинок page.route("**/api/data", lambda route: route.fulfill(status=200, body='{"data": "mock"}')) # Мок API
- Windows (включая WSL)
- macOS (Intel и M1)
- Linux (Ubuntu, Debian, CentOS, RaspbianOS (Raspberry Pi OS))
-
Chromium / Chrome
browser = p.chromium.launch( channel="chrome", # Для запуска браузера, как Google Chrome headless=False, # Показывать браузер slow_mo=100, # Замедление для отладки )
-
Firefox
browser = p.firefox.launch( downloads_path="./downloads", # Путь для загрузок proxy={ # Настройка прокси "server": "http://myproxy.com:3128", "username": "user", "password": "pass" } )
-
WebKit (Safari)
browser = p.webkit.launch( device_scale_factor=2, # Для Retina дисплеев viewport={'width': 1280, 'height': 720} )
# Ожидание загрузки динамического контента
page.wait_for_selector(".dynamic-content")
data = page.query_selector_all(".item")
# Эмуляция мобильного устройства
iphone = p.devices['iPhone 12']
context = browser.new_context(
**iphone,
locale='ru-RU',
geolocation={'latitude': 55.7558, 'longitude': 37.6173},
permissions=['geolocation']
)
# Параллельный парсинг
async def scrape_urls(urls):
browser = await p.chromium.launch()
results = []
async def process_url(url):
context = await browser.new_context()
page = await context.new_page()
await page.goto(url)
data = await page.evaluate('() => document.title')
results.append(data)
await context.close()
await asyncio.gather(*[process_url(url) for url in urls])
await browser.close()
return results
Playwright предоставляет современный, надёжный и эффективный инструментарий для любых задач веб-автоматизации, существенно превосходя конкурентов по многим параметрам. Его архитектура и возможности позволяют решать как простые задачи тестирования, так и сложные сценарии парсинга и автоматизации.
Важно отметить, что правильная настройка таймаутов критически важна для:
- Стабильности автоматизации
- Корректной обработки медленных соединений
- Работы с динамическим контентом
- Обработки краевых случаев загрузки данных
При работе с таймаутами рекомендуется:
- Устанавливать разумные значения по умолчанию
- Переопределять таймауты для специфических операций
- Всегда обрабатывать исключения TimeoutError
- Использовать разные таймауты для разных типов операций
Для комфортной работы с Playwright необходимо:
- Python 3.7 или выше
- Минимум 2 ГБ оперативной памяти
- Около 1 ГБ свободного места на диске (для браузеров)
- Операционная система: Windows 10 или выше, macOS 10.14 или выше, Ubuntu 18.04 или выше
Как обычно, в рамках разработки на Python есть различные варианты установки Playwright, но в целом это создание виртуального окружения, где далее устанавливаются зависимости.
Можно использовать как venv
, uv
или же poetry
.
-
Установка Python и pip
# Проверка версии Python python --version # Обновление pip python -m pip install --upgrade pip
-
Установка Playwright
# Установка основного пакета pip install playwright # Устанавливает все браузеры playwright install # Установка конкретного браузера playwright install chromium playwright install firefox playwright install webkit
Playwright предлагает гибкую систему конфигурации через файлы конфигурации или программный код. Настройки можно задавать через JSON, YAML или Python-файлы. Поддерживается конфигурация на уровне проекта (playwright.config.py), окружения (через переменные окружения) или для конкретного запуска. Основные параметры включают настройки браузера (headless режим, замедление выполнения, размер окна), сетевые параметры (прокси, таймауты, перехват запросов), геолокацию, часовой пояс и локализацию. Для CI/CD окружений можно использовать отдельные конфигурации с автоматическим определением окружения.
VS Code и PyCharm предоставляют встроенную поддержку Playwright через специальные плагины и расширения. Доступны функции автодополнения кода, отладки, запуска тестов и просмотра отчётов. Также поддерживается интеграция с популярными инструментами тестирования: pytest, unittest и другими фреймворками. Для удобства разработки можно использовать Playwright Inspector и Codegen для записи и воспроизведения действий.
Базовые концепции Playwright
Архитектура Playwright
Playwright построен на многоуровневой архитектуре, где каждый уровень отвечает за определённые функции:
- Browser (браузер) - высокоуровневое управление браузером
- BrowserContext (контекст) - изолированная сессия браузера
- Page (страница) - отдельная вкладка или окно
- Frame (фрейм) - работа с iframe и фреймами
- ElementHandle (элемент) - взаимодействие с DOM-элементами
-
Browser
# Один браузер может содержать множество контекстов browser = playwright.chromium.launch() context1 = browser.new_context() context2 = browser.new_context()
-
Browser Context
# Каждый контекст полностью изолирован context = browser.new_context( storage_state="auth.json", # Сохранение состояния record_video_dir="videos/", # Запись видео record_har_path="logs/", # Запись сетевой активности )
Context обеспечивает изоляцию cookies и localStorage, отдельные настройки для каждой сессии, независимую работу с несколькими аккаунтами, параллельное выполнение тестов и различных сценариев.
-
Page
# Страница представляет отдельную вкладку page = context.new_page() page.goto("https://example.com") page.screenshot(path="screenshot.png")
Основные концепции автоматизации
Категория | Метод | Пример | Описание |
---|---|---|---|
Селекторы | Текстовый поиск | page.click(“text=Войти”) | Поиск по видимому тексту |
CSS | page.fill(“input#username”, “admin”) | Стандартные CSS селекторы | |
XPath | page.click(“xpath=//button”) | XPath селекторы | |
Комбинированные | page.click(“article >> text=Подробнее”) | Цепочка селекторов | |
Действия | Клики | click(), dblclick() | Одиночные и двойные клики |
Ввод текста | fill(), type() | Заполнение форм | |
Навигация | goto(), back(), forward() | Перемещение по страницам | |
Скроллинг | scroll_into_view(), mouse.wheel() | Прокрутка страницы | |
Ожидания | Автоматические | page.click() | Встроены в действия |
Явные | wait_for_selector() | Ожидание элементов | |
Пользовательские | wait_for_function() | JavaScript условия | |
События | Сетевые запросы | page.on(‘request’) | Мониторинг запросов |
Консоль | page.on(‘console’) | Логи консоли | |
Диалоги | page.on(‘dialog’) | Всплывающие окна | |
JavaScript | page.on(‘pageerror’) | Ошибки скриптов |
В сердце Playwright лежит уникальная система контекстов браузера. Представьте отдельные песочницы, где каждый тест живёт в своём изолированном мире с собственными cookies, localStorage и sessionStorage. Такая архитектура делает тесты по-настоящему независимыми друг от друга.
При работе с авторизацией и пользовательскими сессиями Playwright раскрывает свой потенциал через механизм сохранения состояния. Вместо утомительного повторения процесса входа в систему достаточно однажды сохранить успешную сессию и использовать её повторно. Это не только ускоряет тесты, но и снижает нагрузку на тестируемое приложение.
Безопасность в Playwright реализована на высшем уровне. Фреймворк предлагает продуманную систему хранения секретных данных – от простых учётных записей до сложных токенов авторизации. Интеграция с переменными окружения открывает гибкие возможности управления конфигурацией в различных средах запуска.
Работа с ресурсами браузера в Playwright организована максимально эффективно. Умное управление памятью автоматически закрывает неиспользуемые соединения и освобождает ресурсы. Параллельное выполнение операций превращает медленные последовательные процессы в быстрые параллельные потоки, существенно сокращая время выполнения задач.
Отладка в Playwright напоминает работу опытного детектива. Встроенный трейсинг фиксирует каждое действие, создавая подробную картину происходящего: от скриншотов ключевых моментов до записи сетевого трафика. Видеозапись выполнения скриптов становится незаменимым инструментом при разборе сложных сценариев взаимодействия с динамическими элементами.
Система мониторинга производительности в Playwright работает как профессиональная метеостанция. Она непрерывно собирает данные о времени загрузки страниц, выполнении JavaScript и сетевой активности. Эти метрики складываются в целостную картину производительности приложения, помогая находить узкие места и оптимизировать работу автоматизированных процессов.
Инструменты диагностики Playwright образуют мощный арсенал разработчика. Встроенный инспектор элементов действует как увеличительное стекло, раскрывая мельчайшие детали структуры страницы. Консоль отладки и точки останова превращают процесс поиска ошибок в методичное расследование. При возникновении проблем Playwright предоставляет исчерпывающий контекст: от состояния страницы до детального лога событий, предшествовавших ошибке.
Приведём множество примеров использования Playwright, которые закрывают большую часть потребностей.
from playwright.sync_api import sync_playwright
def google_search():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
# Открываем Google
page.goto('https://google.com')
# Принимаем cookies если есть
if page.locator('text=Accept all').is_visible():
page.click('text=Accept all')
# Вводим поисковый запрос
page.fill('input[name="q"]', 'Playwright Python')
page.press('input[name="q"]', 'Enter')
# Собираем результаты
results = page.locator('.g')
for i in range(await results.count()):
title = await results.nth(i).locator('h3').text_content()
print(f"Найдено: {title}")
browser.close()
if __name__ == "__main__":
google_search()
Playwright предлагает несколько мощных способов поиска и взаимодействия с элементами:
# Современный подход с локаторами
page.get_by_role('button', name='Submit').click()
page.get_by_text('Welcome').is_visible()
page.get_by_label('Password').fill('secret')
page.get_by_placeholder('Search').type('query')
# Работа с формами
page.get_by_role('textbox').fill('text')
page.get_by_role('checkbox').check()
page.select_option('select#country', 'Russia')
# Сложные взаимодействия
page.drag_and_drop('#source', '#target')
page.hover('.menu-item')
page.keyboard.press('Control+A')
# Загрузка файла
with page.expect_file_chooser() as fc_info:
page.click('button#upload')
file_chooser = fc_info.value
file_chooser.set_files('path/to/file.pdf')
# Скачивание файла
with page.expect_download() as download_info:
page.click('a#download-link')
download = download_info.value
download.save_as('my_file.pdf')
# Открытие новой вкладки
with page.expect_popup() as popup_info:
page.click('a[target="_blank"]')
popup = popup_info.value
# Работа со всеми вкладками
all_pages = page.context.pages
for tab in all_pages:
print(await tab.title())
# Мониторинг запросов
page.on('request', lambda request: print(request.url))
page.on('response', lambda response: print(response.status))
# Модификация ответов
def handle_route(route):
if 'api/data' in route.request.url:
route.fulfill(
status=200,
body=json.dumps({'custom': 'data'})
)
else:
route.continue_()
page.route('**/*', handle_route)
# Ожидание изменений на странице
page.wait_for_load_state('networkidle')
page.wait_for_selector('.dynamic-content')
page.wait_for_function('window.status === "ready"')
# Бесконечная прокрутка
while True:
last_height = page.evaluate('document.body.scrollHeight')
page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
try:
page.wait_for_function(
f'document.body.scrollHeight > {last_height}',
timeout=5000
)
except TimeoutError:
break
# Прямой доступ к элементам в Shadow DOM
page.locator('custom-element').get_by_text('Click me').click()
# Сложная навигация по Shadow DOM
page.locator('host-element')
.locator('::shadow')
.locator('button')
.click()
from playwright.sync_api import sync_playwright, Devices
def test_mobile():
with sync_playwright() as p:
iphone = p.devices['iPhone 12']
browser = p.webkit.launch()
context = browser.new_context(
**iphone,
locale='ru-RU',
geolocation={'latitude': 55.7558, 'longitude': 37.6173},
permissions=['geolocation']
)
page = context.new_page()
page.goto('https://example.com')
Каждый из этих примеров демонстрирует практическое применение Playwright в реальных сценариях автоматизации. Фреймворк предоставляет интуитивно понятный API для решения как простых, так и сложных задач автоматизации веб-приложений.
Playwright предоставляет мощный и современный инструментарий для автоматизации веб-тестирования. Его активное развитие и поддержка сообщества делают его отличным выбором как для начинающих, так и для опытных специалистов по автоматизации, активно развивается в ключевых направлениях:
- Расширение возможностей для тестирования мобильных веб-приложений
- Улучшение производительности и стабильности
- Интеграция с новыми инструментами и фреймворками
- Поддержка новых веб-технологий и стандартов