Playwright Python — справочник На главный сайт

Синхронный API: sync_playwright

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

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.title())
    browser.close()

Контекстный менеджер with sync_playwright() as p: автоматически запускает Playwright и корректно завершает все процессы браузера при выходе из блока. Это гарантирует, что фоновые процессы браузера не останутся в памяти.

Пошаговый разбор базового примера

# 1. Импорт синхронного API
from playwright.sync_api import sync_playwright

# 2. Запуск Playwright через контекстный менеджер
with sync_playwright() as p:
    # 3. Запуск браузера (headless=False — показывать окно)
    browser = p.chromium.launch(headless=False)

    # 4. Создание новой страницы
    page = browser.new_page()

    # 5. Навигация на URL
    page.goto("https://example.com")

    # 6. Использование локаторов для взаимодействия
    heading = page.locator("h1")
    print(heading.text_content())

    # 7. Закрытие браузера
    browser.close()

Ручной запуск браузера

Вы можете запустить любой поддерживаемый браузер с различными опциями.

with sync_playwright() as p:
    # Chromium
    chromium = p.chromium.launch(headless=True)

    # Firefox
    firefox = p.firefox.launch()

    # WebKit (Safari)
    webkit = p.webkit.launch()

    # С дополнительными опциями
    browser = p.chromium.launch(
        headless=False,
        slow_mo=100,            # задержка между действиями (мс)
        args=["--disable-blink-features=AutomationControlled"],
        proxy={"server": "http://proxy:8080"},
    )

    # Создание страницы
    page = browser.new_page()
    page.goto("https://example.com")
    browser.close()

Создание страницы и основные операции

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

    # Навигация
    page.goto("https://example.com", wait_until="networkidle")

    # Поиск элементов через локаторы
    button = page.locator("#submit")
    button.click()

    # Семантические локаторы
    page.get_by_role("button", name="Submit").click()
    page.get_by_text("Welcome").click()
    page.get_by_label("Email").fill("user@example.com")

    # Извлечение данных
    title = page.title()
    url = page.url
    content = page.content()
    text = page.locator(".content").text_content()

    browser.close()

Закрытие браузера

Всегда закрывайте браузер после использования, чтобы освободить системные ресурсы. Если вы используете контекстный менеджер sync_playwright(), браузер всё равно нужно закрывать явно, если только вы не используете browser внутри with.

# Вариант 1: явное закрытие
browser = p.chromium.launch()
# ... работа с браузером
browser.close()

# Вариант 2: контекстный менеджер браузера
with p.chromium.launch() as browser:
    page = browser.new_page()
    page.goto("https://example.com")
    # браузер закроется автоматически

Асинхронный API: async_playwright

Для асинхронных приложений (FastAPI, aiohttp, asyncio) Playwright предоставляет асинхронный API через модуль async_api. Все методы возвращают корутины и требуют await.

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("https://example.com")
        title = await page.title()
        print(title)
        await browser.close()

asyncio.run(main())

Асинхронные операции детально

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

        await page.goto("https://example.com")
        await page.get_by_role("button", name="Start").click()
        text = await page.locator("#result").text_content()
        print(text)

        await browser.close()

Когда использовать async: Асинхронный API идеально подходит для веб-скрапинга с параллельной обработкой нескольких страниц, интеграции с веб-фреймворками (FastAPI, Sanic) и обработки большого количества URL без блокировки основного потока.

Сравнение sync vs async

Характеристикаsync_playwrightasync_playwright
Импортfrom playwright.sync_api import sync_playwrightfrom playwright.async_api import async_playwright
Запускwith sync_playwright() as p:async with async_playwright() as p:
ВызовыСинхронные, без awaitВсе методы await
ПроизводительностьБлокирующий, один потокНеблокирующий, event loop
Когда использоватьpytest, скрипты, парсингFastAPI, aiohttp, asyncio
ПараллелизмЧерез потоки/процессыЧерез asyncio.gather()
СложностьНиже, проще отладкаВыше, требуется понимание asyncio

Использование без pytest

Playwright как автономная библиотека идеально подходит для задач, не связанных с тестированием:

  • Веб-скрапинг: извлечение данных с динамических страниц, рендерящих контент через JavaScript
  • Парсинг SPA: одностраничные приложения на React, Vue, Angular, где обычный HTTP-запрос не возвращает готовый HTML
  • Генерация PDF: создание PDF-документов из HTML-страниц с точным рендерингом
  • Скриншоты: автоматическое создание скриншотов страниц для отчётов или мониторинга
  • Автоматизация: заполнение форм, навигация, мониторинг статуса веб-сервисов

Пример: получение данных со страницы

from playwright.sync_api import sync_playwright

def scrape_products(url):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until="networkidle")

        products = []
        items = page.locator(".product").all()
        for item in items:
            products.append({
                "name": item.locator(".name").text_content(),
                "price": item.locator(".price").text_content(),
            })

        browser.close()
        return products

data = scrape_products("https://example.com/products")
print(data)

Пример: генерация PDF

from playwright.sync_api import sync_playwright

def generate_pdf(url, output_path):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until="networkidle")
        page.pdf(path=output_path, format="A4")
        browser.close()

generate_pdf("https://example.com/report", "report.pdf")

Полный пример скрипта с sync_playwright

from playwright.sync_api import sync_playwright

def main():
    with sync_playwright() as p:
        # Запуск браузера
        browser = p.chromium.launch(headless=False)
        context = browser.new_context(
            viewport={"width": 1280, "height": 720},
            locale="ru-RU"
        )
        page = context.new_page()

        # Переход на сайт
        page.goto("https://github.com")
        print(f"Заголовок: {page.title()}")

        # Поиск
        page.get_by_role("combobox", name="Search").click()
        page.get_by_role("combobox", name="Search").fill("playwright")
        page.keyboard.press("Enter")
        page.wait_for_load_state("networkidle")

        # Скриншот результатов
        page.screenshot(path="search_results.png")

        # Закрытие
        browser.close()

if __name__ == "__main__":
    main()

Асинхронный пример с параллельными задачами

import asyncio
from playwright.async_api import async_playwright

async def process_url(url, semaphore):
    async with semaphore:
        async with async_playwright() as p:
            browser = await p.chromium.launch()
            page = await browser.new_page()
            await page.goto(url, wait_until="domcontentloaded")
            title = await page.title()
            await browser.close()
            return {"url": url, "title": title}

async def main():
    urls = [
        "https://example.com",
        "https://playwright.dev",
        "https://github.com",
        "https://python.org",
    ]
    semaphore = asyncio.Semaphore(2)
    tasks = [process_url(url, semaphore) for url in urls]
    results = await asyncio.gather(*tasks)

    for r in results:
        print(f"{r['url']}: {r['title']}")

asyncio.run(main())

Внимание: Каждый вызов async_playwright() и browser.launch() создаёт тяжёлые процессы. В асинхронном режиме используйте семафоры или пул браузеров для контроля параллелизма. Запускать браузер для каждого URL — расточительно; переиспользуйте один браузер с разными страницами.

Заключение

Автономная библиотека Playwright даёт полный контроль над браузером без привязки к тестовым раннерам. Используйте синхронный API для простых скриптов и парсинга, асинхронный — для высоконагруженных приложений и интеграции с async-фреймворками. Всегда закрывайте браузер после работы и используйте контекстные менеджеры для безопасного управления ресурсами.