Плейрайтер: Веб-скрейпинг и тестирование

Освойте автоматизацию браузеров для тестирования веб приложений

Содержимое страницы

Playwright — это мощный современный фреймворк для автоматизации браузеров, который революционизирует веб-скрейпинг и тестирование веб приложений.

Разработанный компанией Microsoft, он предоставляет унифицированный API для автоматизации браузеров Chromium, Firefox и WebKit с беспрецедентной надежностью и скоростью.

playwright ui

Что такое Playwright?

Playwright — это фреймворк с открытым исходным кодом для автоматизации браузеров, который позволяет разработчикам создавать надежные тесты end-to-end и строить сложные решения для веб-скрейпинга. В отличие от традиционных инструментов автоматизации, Playwright был разработан с нуля для работы с современными веб-приложениями с динамическим контентом, одностраничными приложениями (SPA) и сложными JavaScript-фреймворками.

Фреймворк решает ключевую проблему, которая мучила предыдущие инструменты автоматизации: нестабильность. Playwright внедряет механизмы автоматического ожидания, которые автоматически ждут, пока элементы станут доступными для действий перед выполнением операций, устраняя необходимость в произвольных таймаутах и паузах, которые делали тесты ненадежными.

Основные возможности

Поддержка нескольких браузеров: Playwright поддерживает все основные браузерные движки — Chromium (включая Chrome и Edge), Firefox и WebKit (Safari). Это означает, что вы можете написать скрипт автоматизации один раз и запустить его в разных браузерах без изменений, обеспечивая согласованную работу ваших веб-приложений везде.

Автоматическое ожидание: Одна из самых мощных функций Playwright — это встроенный механизм автоматического ожидания. Перед выполнением любого действия Playwright автоматически ждет, пока элементы станут видимыми, включенными, стабильными и не скрытыми. Это устраняет гонки данных и делает тесты значительно более надежными по сравнению с инструментами вроде Selenium, где часто требуются явные ожидания.

Перехват сети: Playwright позволяет перехватывать, изменять и имитировать сетевые запросы и ответы. Это бесценно для тестирования крайних случаев, симуляции медленных сетей, блокировки ненужных ресурсов во время скрейпинга или имитации ответов API без необходимости в бэкенде.

Эмуляция мобильных устройств: Тестируйте мобильные веб-приложения, эмулируя различные мобильные устройства с определенными размерами viewport, пользовательскими агентами и событиями касания. Playwright включает в себя описания устройств для популярных смартфонов и планшетов.

Мощные селекторы: Помимо CSS и XPath селекторов, Playwright поддерживает текстовые селекторы, селекторы на основе ролей для тестирования доступности и даже экспериментальные React и Vue селекторы для компонентных фреймворков.

Установка и настройка

Настройка Playwright проста для разных языков программирования.

Установка для Python

Для проектов на Python Playwright можно установить через pip и он включает как синхронные, так и асинхронные API. Если вы ищете более быстрый, современный менеджер пакетов для Python, ознакомьтесь с нашим руководством по uv - Python Package, Project, and Environment Manager:

# Установка пакета Playwright
pip install playwright

# Установка браузеров (Chromium, Firefox, WebKit)
playwright install

# Только для конкретного браузера
playwright install chromium

Для всестороннего справочника по синтаксису Python и часто используемым командам при работе с Playwright обратитесь к нашему Python Cheatsheet.

Установка для JavaScript/TypeScript

Для проектов на Node.js установите Playwright через npm или yarn:

# Используя npm
npm init playwright@latest

# Используя yarn
yarn create playwright

# Ручная установка
npm install -D @playwright/test
npx playwright install

Команда npm init playwright предоставляет интерактивную настройку, которая конфигурирует ваш проект с примерными тестами, файлами конфигурации и workflow GitHub Actions.

Базовая конфигурация

Создайте файл playwright.config.ts (TypeScript) или playwright.config.js (JavaScript):

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  timeout: 30000,
  retries: 2,
  workers: 4,
  use: {
    headless: true,
    viewport: { width: 1280, height: 720 },
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
});

Веб-скрейпинг с Playwright

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

Базовый пример скрейпинга

Вот всесторонний пример на Python, демонстрирующий основные концепции скрейпинга:

from playwright.sync_api import sync_playwright
import json

def scrape_website():
    with sync_playwright() as p:
        # Запуск браузера
        browser = p.chromium.launch(headless=True)

        # Создание контекста для изоляции
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080},
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        )

        # Открытие новой страницы
        page = context.new_page()

        # Переход по URL
        page.goto('https://example.com/products')

        # Ожидание загрузки контента
        page.wait_for_selector('.product-item')

        # Извлечение данных
        products = page.query_selector_all('.product-item')

        data = []
        for product in products:
            title = product.query_selector('h2').inner_text()
            price = product.query_selector('.price').inner_text()
            url = product.query_selector('a').get_attribute('href')

            data.append({
                'title': title,
                'price': price,
                'url': url
            })

        # Очистка
        browser.close()

        return data

# Запуск скрейпера
results = scrape_website()
print(json.dumps(results, indent=2))

Обработка динамического контента

Современные сайты часто загружают контент динамически через JavaScript. Playwright обрабатывает это без проблем:

async def scrape_dynamic_content():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()

        await page.goto('https://example.com/infinite-scroll')

        # Прокрутка для загрузки большего количества контента
        for _ in range(5):
            await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
            await page.wait_for_timeout(2000)

        # Ожидание завершения сетевых операций
        await page.wait_for_load_state('networkidle')

        # Извлечение всех загруженных элементов
        items = await page.query_selector_all('.item')

        await browser.close()

Преобразование скрейпинга контента в Markdown

После извлечения HTML-контента с помощью Playwright часто требуется преобразовать его в более удобный формат. Для всесторонних руководств по преобразованию HTML в Markdown ознакомьтесь с нашими статьями Преобразование HTML в Markdown с помощью Python: Всестороннее руководство, которое сравнивает 6 различных Python-библиотек, и Преобразование HTML-контента в Markdown с использованием LLM и Ollama для преобразования с использованием ИИ. Если вы работаете с документами Word, ознакомьтесь с нашим руководством по Преобразованию документов Word в Markdown.

Аутентификация и управление сессиями

Когда скрейпинг требует аутентификации, Playwright упрощает сохранение и повторное использование состояния браузера:

def login_and_save_session():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()

        # Вход в систему
        page.goto('https://example.com/login')
        page.fill('input[name="username"]', 'your_username')
        page.fill('input[name="password"]', 'your_password')
        page.click('button[type="submit"]')

        # Ожидание навигации после входа
        page.wait_for_url('**/dashboard')

        # Сохранение аутентифицированного состояния
        context.storage_state(path='auth_state.json')

        browser.close()

def scrape_with_saved_session():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        # Повторное использование сохраненного состояния аутентификации
        context = browser.new_context(storage_state='auth_state.json')
        page = context.new_page()

        # Уже аутентифицирован!
        page.goto('https://example.com/protected-data')
        # ... скрейпинг защищенного контента

        browser.close()

Этот подход особенно полезен при работе с API или создании MCP-серверов для интеграции ИИ. Для полного руководства по реализации веб-скрейпинга в интеграции инструментов ИИ ознакомьтесь с нашей статьей Создание MCP-серверов на Python: WebSearch & Scrape.

Тестирование “от конца до начала”

Основное применение Playwright — написание надежных тестов “от конца до начала” для веб-приложений.

Написание первого теста

Вот полный пример теста на TypeScript:

import { test, expect } from '@playwright/test';

test('пользователь может добавить товар в корзину', async ({ page }) => {
  // Переход на главную страницу
  await page.goto('https://example-shop.com');

  // Поиск товара
  await page.fill('[data-testid="search-input"]', 'ноутбук');
  await page.press('[data-testid="search-input"]', 'Enter');

  // Ожидание результатов поиска
  await expect(page.locator('.product-card')).toBeVisible();

  // Нажатие на первый товар
  await page.locator('.product-card').first().click();

  // Проверка загрузки страницы товара
  await expect(page).toHaveURL(/\/product\/.+/);

  // Добавление в корзину
  await page.click('[data-testid="add-to-cart"]');

  // Проверка обновления корзины
  const cartCount = page.locator('[data-testid="cart-count"]');
  await expect(cartCount).toHaveText('1');
});

Модель объектов страниц

Для больших наборов тестов используйте модель объектов страниц для повышения поддерживаемости:

// pages/LoginPage.ts
export class LoginPage {
  constructor(private page: Page) {}

  async navigate() {
    await this.page.goto('/login');
  }

  async login(username: string, password: string) {
    await this.page.fill('[name="username"]', username);
    await this.page.fill('[name="password"]', password);
    await this.page.click('button[type="submit"]');
  }

  async getErrorMessage() {
    return await this.page.locator('.error-message').textContent();
  }
}

// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';

test('вход с неверными учетными данными показывает ошибку', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.navigate();
  await loginPage.login('invalid@email.com', 'wrongpass');

  const error = await loginPage.getErrorMessage();
  expect(error).toContain('Неверные учетные данные');
});

Дополнительные функции

Codegen - Автоматическая генерация тестов

Инструмент Codegen Playwright генерирует тесты, записывая ваши взаимодействия с веб-страницей:

# Открыть Codegen
playwright codegen example.com

# С конкретным браузером
playwright codegen --browser firefox example.com

# С сохраненным состоянием аутентификации
playwright codegen --load-storage=auth.json example.com

По мере взаимодействия со страницей Codegen генерирует код в реальном времени. Это невероятно полезно для быстрого прототипирования тестов или изучения синтаксиса селекторов Playwright.

Трейс-визуализатор для отладки

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

// Включение трассировки в конфигурации
use: {
  trace: 'on-first-retry',
}

После падения теста и его повторного запуска просмотрите трассировку:

playwright show-trace trace.zip

Трейс-визуализатор показывает скриншоты каждого действия, сетевую активность, логи консоли и снимки DOM, что делает отладку простой.

Перехват и имитация сети

Перехватывайте и изменяйте сетевой трафик для тестирования крайних случаев:

def test_with_mocked_api():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()

        # Имитация ответа API
        def handle_route(route):
            if 'api/products' in route.request.url:
                route.fulfill(
                    status=200,
                    body=json.dumps({
                        'products': [
                            {'id': 1, 'name': 'Тестовый товар', 'price': 99.99}
                        ]
                    })
                )
            else:
                route.continue_()

        page.route('**/*', handle_route)

        page.goto('https://example.com')
        # Страница теперь использует имитированные данные

        browser.close()

Тестирование мобильных устройств

Тестируйте свои адаптивные дизайны на различных устройствах:

from playwright.sync_api import sync_playwright

def test_mobile():
    with sync_playwright() as p:
        # Использование описания устройства
        iphone_13 = p.devices['iPhone 13']

        browser = p.webkit.launch()
        context = browser.new_context(**iphone_13)
        page = context.new_page()

        page.goto('https://example.com')

        # Взаимодействие как мобильный пользователь
        page.locator('#mobile-menu-button').click()

        browser.close()

Лучшие практики

Для веб-скрейпинга

  1. Используйте безголовый режим в продакшене: Безголовое просмотр быстрее и использует меньше ресурсов
  2. Реализуйте ограничение скорости: Уважайте целевые сайты, добавляя задержки между запросами
  3. Обрабатывайте ошибки корректно: Сетевые проблемы, таймауты и изменения селекторов случаются
  4. Вращайте User Agents: Избегайте обнаружения, изменяя отпечатки браузеров
  5. Уважайте robots.txt: Проверяйте и следуйте политикам скрейпинга сайтов
  6. Используйте изоляцию контекста: Создавайте отдельные контексты браузера для параллельного скрейпинга

При конвертации скрейпинга в формат markdown рассмотрите использование инструментов на основе LLM или Python-библиотек, специализированных для конвертации HTML в Markdown, для более чистого вывода.

Для тестирования

  1. Используйте атрибуты data-testid: Они более стабильны, чем CSS-классы, которые часто меняются
  2. Избегайте жестких ожиданий: Используйте встроенные механизмы ожидания Playwright вместо sleep()
  3. Держите тесты независимыми: Каждый тест должен быть способен выполняться изолированно
  4. Используйте фикстуры: Эффективно делите код настройки между тестами
  5. Запускайте тесты параллельно: Используйте потоки Playwright для ускорения
  6. Записывайте трассировки при сбое: Включите запись трассировок для более простой отладки

Оптимизация производительности

# Отключение ненужных ресурсов
def fast_scraping():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context()
        page = context.new_page()

        # Блокируем изображения и таблицы стилей для ускорения скрейпинга
        async def block_resources(route):
            if route.request.resource_type in ['image', 'stylesheet', 'font']:
                await route.abort()
            else:
                await route.continue_()

        page.route('**/*', block_resources)
        page.goto('https://example.com')

        browser.close()

Сравнение Playwright с альтернативами

Playwright vs Selenium

Преимущества Playwright:

  • Встроенное автоматическое ожидание устраняет нестабильные тесты
  • Быстрое выполнение благодаря современной архитектуре
  • Лучшее перехват и имитация сети
  • Превосходные инструменты отладки (Трейс-визуализатор)
  • Проще API с меньшим количеством шаблонного кода
  • Поддержка нескольких браузеров с одной установкой

Преимущества Selenium:

  • Более зрелая экосистема с обширным сообществом
  • Поддержка большего количества языков программирования
  • Более широкая совместимость с браузерами, включая старые версии

Playwright vs Puppeteer

Преимущества Playwright:

  • Истинная кросс-браузерная поддержка (Firefox, WebKit, Chromium)
  • Лучший дизайн API на основе уроков Puppeteer
  • Более мощные инструменты отладки
  • Поддержка Microsoft и активное развитие

Преимущества Puppeteer:

  • Немного меньший размер
  • Экспертиза Chrome DevTools Protocol

Для большинства новых проектов Playwright является рекомендуемым выбором благодаря своей современной архитектуре и всеобъемлющему набору функций. Если вы работаете с Go вместо Python или JavaScript и вам нужны возможности веб-скрейпинга, ознакомьтесь с нашим руководством по Альтернативам Beautiful Soup для Go для аналогичных инструментов скрейпинга в экосистеме Go.

Общие случаи использования

Извлечение данных для приложений AI/LLM

Playwright отлично подходит для сбора обучающих данных или создания возможностей веб-поиска для моделей ИИ. При создании серверов MCP (Model Context Protocol) Playwright может обрабатывать компонент веб-скрейпинга, в то время как LLM обрабатывают извлеченный контент.

Автоматизированное тестирование в CI/CD

Интегрируйте тесты Playwright в ваш конвейер непрерывной интеграции:

# .github/workflows/playwright.yml
name: Playwright Tests
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: 18
    - name: Установка зависимостей
      run: npm ci
    - name: Установка браузеров Playwright
      run: npx playwright install --with-deps
    - name: Запуск тестов Playwright
      run: npx playwright test
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

Мониторинг веб-сайтов

Мониторьте ваши производственные сайты на предмет доступности и функциональности:

import schedule
import time

def monitor_website():
    with sync_playwright() as p:
        try:
            browser = p.chromium.launch()
            page = browser.new_page()
            page.goto('https://your-site.com', timeout=30000)

            # Проверка критических элементов
            assert page.is_visible('.header')
            assert page.is_visible('#main-content')

            print("✓ Веб-сайт работает нормально")
        except Exception as e:
            print(f"✗ Обнаружена проблема с сайтом: {e}")
            # Отправить уведомление
        finally:
            browser.close()

# Запуск каждые 5 минут
schedule.every(5).minutes.do(monitor_website)

while True:
    schedule.run_pending()
    time.sleep(1)

Устранение распространенных проблем

Проблемы с установкой браузеров

Если браузеры не удается загрузить:

# Установить пользовательское расположение загрузки
PLAYWRIGHT_BROWSERS_PATH=/custom/path playwright install

# Очистить кеш и переустановить
playwright uninstall
playwright install

Ошибки таймаута

Увеличьте таймауты для медленных сетей или сложных страниц:

page.goto('https://slow-site.com', timeout=60000)  # 60 секунд
page.wait_for_selector('.element', timeout=30000)  # 30 секунд

Селектор не найден

Используйте Playwright Inspector для идентификации правильных селекторов:

PWDEBUG=1 pytest test_file.py

Это открывает инспектор, где вы можете навести курсор на элементы, чтобы увидеть их селекторы.

Заключение

Playwright представляет собой передовую технологию автоматизации браузеров, сочетающую мощные функции с отличным пользовательским опытом разработчика. Будь то создание конвейера веб-скрейпинга, реализация всеобъемлющего покрытия тестами или создание автоматизированных рабочих процессов, Playwright предоставляет необходимые инструменты и надежность.

Его механизмы автоматического ожидания устраняют ненадежные тесты, поддержка нескольких браузеров гарантирует, что ваши приложения работают везде, а мощные инструменты отладки делают устранение неполадок простым. По мере того как веб-приложения продолжают расти в сложности, современная архитектура Playwright и активная разработка делают его отличным выбором для любых задач автоматизации браузеров.

Для разработчиков на Python, работающих над конвейерами данных или проектами веб-скрейпинга, Playwright интегрируется без проблем с современными менеджерами пакетов и отлично работает вместе с pandas, requests и другими инструментами анализа данных. Возможность извлекать структурированные данные из сложных современных веб-сайтов делает его бесценным для приложений ИИ, исследовательских проектов и бизнес-аналитики. В сочетании с инструментами преобразования HTML в Markdown и правильной обработкой контента Playwright становится полным решением для извлечения, преобразования и использования веб-данных в масштабах.

Полезные ссылки

Другие ссылки