Playwright парсинг: браузер для JS-сайтов

Playwright — автоматизация браузера для парсинга динамических сайтов. Когда он нужен вместо Scrapy, чем отличается от Puppeteer и Selenium.

← Все статьи

playwright парсинг

Playwright парсинг — извлечение данных через реальный браузер (Chromium/Firefox/WebKit): JS исполняется, блоки появляются после скролла и кликов, можно перехватывать XHR/JSON. Для статичных витрин дешевле Beautiful Soup или Scrapy; рядом — Puppeteer и Selenium. Ниже — сценарии, код и сравнение.

playwright парсинг

Кратко

  • Playwright: навигация, авто-ожидания, ввод, network intercept.
  • Сильнее HTTP-стека на SPA и многошаговых UI-потоках.
  • Дороже по CPU/RAM, чем лёгкие HTTP-запросы.
  • Антибот не снимается «сам» — нужны легальная модель доступа и адекватные лимиты.
  • Паттерн продакшена: очередь + Playwright только на тяжёлых URL.
playwright парсинг

Инфографика: открытие страницы → ожидание рендера/сети → извлечение полей или JSON из XHR.

Типовые задачи

ЗадачаПодходСложностьКогда не подходит
SPA-каталогgoto + wait_for_selectorСредняяДанные уже в HTML/API
Фильтры и пагинация UIclick + waitСредняя–высокаяНет стабильных селекторов
Забрать JSON из Networkpage.on(«response»)СредняяОтветы бинарные/шифрованные
Массовый краул 100kОчередь + пул браузеровВысокаяБюджет только на HTTP

Пример кода: extract + перехват XHR

from playwright.sync_api import sync_playwright

def scrape_listing(url: str) -> list[dict]:
    items = []
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()

        def on_response(resp):
            if "api/products" in resp.url and resp.status == 200:
                try:
                    payload = resp.json()
                    items.extend(payload.get("items", []))
                except Exception:
                    pass

        page.on("response", on_response)
        page.goto(url, wait_until="networkidle")
        page.wait_for_selector(".product-card", timeout=15000)

        # Fallback: DOM, если API не поймали
        if not items:
            cards = page.query_selector_all(".product-card")
            for card in cards:
                items.append({
                    "title": card.query_selector("h2").inner_text().strip(),
                    "price": card.query_selector(".price").inner_text().strip(),
                })
        browser.close()
    return items

Когда Playwright оправдан

  1. Контент появляется только после JS или взаимодействия.
  2. Нужен логин, cookies, сложный UI-поток.
  3. Удобнее забирать JSON из Network, чем парсить DOM.
  4. Команда уже использует Playwright в e2e.
  5. Объём умеренный: сотни–тысячи страниц, не миллионы «в лоб».

Сравнение браузерных инструментов

КритерийPlaywrightPuppeteerSelenium
БраузерыChromium, Firefox, WebKitВ основном ChromiumШирокая матрица
Авто-ожиданияСильныеХорошиеЧаще ручные waits
ЯзыкиJS/TS, Python, Java, .NETNodeМногоязычный
Новые проекты 2026Частый выборСилён в NodeLegacy QA

Ограничения

Playwright не заменяет юридическую оценку источника. На защищённых витринах растёт стоимость прокси и поддержки селекторов.

Когда не подходит

Не гоняйте Playwright там, где хватает HTML/API. No-code — ParseHub / Octoparse. Облако акторов — Apify.

FAQ

Playwright быстрее Selenium?

На типичных сценариях — да: меньше flaky waits.

Python или Node?

Оба поддерживаются — выбирайте язык команды.

Можно ли с Scrapy?

Да: Scrapy ведёт очередь, Playwright рендерит отдельные страницы.

Заказной парсинг JS-витрин: парсинг сайтов. Серия: Puppeteer, Selenium.