Бывает, что парсер получает пустую страницу, хотя в браузере товары видны. Причина — динамическая загрузка: данные подтягиваются скриптами уже после открытия страницы, и в исходном 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 или парсинг сайтов под ключ.