Написати в Телеграм Написати у Вайбер Зателефонувати

Бывает, что парсер получает пустую страницу, хотя в браузере товары видны. Причина — динамическая загрузка: данные подтягиваются скриптами уже после открытия страницы, и в исходном HTML их нет. Разбираем, как с этим работать на Python.

Как понять, что страница динамическая

  • В «Просмотре кода страницы» (Ctrl+U) нет нужного текста, хотя в браузере он есть.
  • Контент появляется после прокрутки или нажатия кнопки «Показать ещё».
  • В ответе requests лишь пустой контейнер, например <div id="app"></div>.

Способ 1. Найти скрытый запрос к API

Самый быстрый путь: откройте DevTools (F12) → вкладка Network → фильтр Fetch/XHR и перезагрузите страницу. Часто данные приходят отдельным запросом в формате JSON. Его можно воспроизвести обычным requests: это быстрее и дешевле, чем запускать браузер.

import requests

r = requests.get("https://example.com/api/products?page=1",
                 headers={"User-Agent": "Mozilla/5.0"}, timeout=20)
data = r.json()
for item in data["items"]:
    print(item["name"], item["price"])

Способ 2. Selenium

Selenium управляет настоящим браузером, поэтому видит страницу после выполнения скриптов.

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

driver = webdriver.Chrome()
driver.get("https://example.com/catalog")

WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".product-card"))
)

for card in driver.find_elements(By.CSS_SELECTOR, ".product-card"):
    print(card.find_element(By.CSS_SELECTOR, ".title").text)

driver.quit()

Обязательно используйте явные ожидания (WebDriverWait), а не фиксированные паузы: так парсер не сработает раньше, чем данные появятся.

Способ 3. Playwright

Современная альтернатива Selenium: быстрее, удобнее в настройке и со встроенными ожиданиями.

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com/catalog")
    page.wait_for_selector(".product-card")
    titles = page.locator(".product-card .title").all_inner_texts()
    browser.close()

print(titles)

Перед первым запуском выполните pip install playwright и playwright install chromium.

Бесконечная прокрутка и кнопка «Показать ещё»

В Selenium или Playwright прокручивайте страницу в цикле и проверяйте, увеличилось ли количество элементов. Когда новых нет — останавливайтесь. Для кнопки «Показать ещё» нажимайте её, пока она не исчезнет.

Советы для стабильной работы

  • Сначала ищите JSON-запрос: браузер нужен только там, где иначе не получится.
  • Режим headless быстрее, но некоторые сайты его распознают. Тогда помогают реальный User-Agent и размеры окна.
  • Не запускайте десятки окон одновременно: это нагружает и ваш компьютер, и чужой сайт.
  • Закрывайте браузер в блоке finally, чтобы не оставлять фоновые процессы.

Базовые примеры со статическими страницами смотрите в статье парсинг на Python с BeautifulSoup.

Сложный сайт с защитой или динамикой? Разработаем решение под вас: заказать парсер на Python или парсинг сайтов под ключ.