Скрейпинг динамических каталогов интернет-магазинов
Как собирать данные о товарах с платформ e-commerce на React: настройка JS-рендеринга, extract_schema, обход rate limits и batch-сбор каталогов 10 000+ позиций.
Команда InfraProxy
20 февраля 2026 г.
Почему SPA-платформы e-commerce сложно скрейпить
Многие интернет-магазины строятся на SPA (Single Page Application): React, Vue или аналогичных фреймворках. Данные о товарах загружаются через API после выполнения JavaScript. Для скрейпинга это создаёт несколько серьёзных преград.
React-рендеринг. HTML страницы изначально минимален — карточки товаров, цены, описания подгружаются асинхронно. Обычный HTTP-запрос возвращает пустой каркас с placeholder-блоками.
Стены антиботов. E-commerce-платформы защищают каталоги от парсеров: проверка TLS-отпечатков, детектирование headless-браузеров, блокировка по IP. Датацентровые запросы быстро получают 403 или CAPTCHA.
Rate limits. Ограничения на частоту запросов и подозрительные паттерны приводят к временной блокировке. Сбор больших каталогов требует ротации IP и контролируемой скорости.
Для стабильного сбора нужен API с JavaScript-рендерингом, обходом антиботов, резидентными прокси и грамотной настройкой ожидания загрузки.
Настройка запросов с JS-рендерингом для динамического контента
Базовый запрос к каталогу интернет-магазина:
import httpx
import os
API_KEY = os.environ.get("SCRAPER_API_KEY")
BASE_URL = "https://api.example.com/v1/scrape"
payload = {
"url": "https://example.com/collections/electronics",
"use_js_render": True,
"js_wait_for": ".product-grid, .product-card",
"use_residential": True
}
with httpx.Client(timeout=60.0) as client:
resp = client.post(
BASE_URL,
json=payload,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
)
resp.raise_for_status()
Параметр js_wait_for указывает селектор, по появлению которого API считает страницу готовой. Для каталогов товаров это обычно контейнер с карточками (.product-grid, .product-card). Без такого ожидания извлечение данных может произойти до завершения рендеринга, и результат будет пустым.
Извлечение структурированных данных через extract_schema
Для товарных каталогов удобно использовать extract_schema — описание целевой JSON-схемы. API извлекает данные по смыслу, а не по жёстким селекторам, что устойчивее к изменениям вёрстки:
{
"url": "https://example.com/products/laptop-pro",
"use_js_render": true,
"js_wait_for": ".product-detail",
"extract_schema": {
"title": {"type": "string"},
"price": {"type": "number"},
"currency": {"type": "string"},
"description": {"type": "string"},
"availability": {"type": "string"},
"variants": {
"type": "array",
"items": {
"name": {"type": "string"},
"price": {"type": "number"},
"sku": {"type": "string"}
}
}
}
}
Схема описывает, что нужно извлечь, а не как это выражено в DOM. При A/B-тестах и редизайнах такая экстракция часто остаётся рабочей дольше, чем extract_rules.
Обработка rate limits: session_id и резидентные прокси
При сборе большого каталога (сотни и тысячи страниц) rate limits становятся критичным фактором.
session_id для сессионной привязки
Используйте один и тот же session_id для всех запросов в рамках одного «сеанса» обхода каталога. API будет направлять трафик через один IP и сохранять cookies. Это снижает вероятность CAPTCHA при переходе со страницы на страницу и выглядит более естественно для антибот-системы.
payload = {
"url": url,
"use_js_render": True,
"session_id": "catalog-crawl-001",
"extract_schema": product_schema
}
Резидентные прокси
E-commerce-платформы активно блокируют датацентровые IP. Параметр use_residential: true переключает запросы на резидентные прокси — IP домашних провайдеров с высокой репутацией. Это значительно повышает success rate при большом объёме запросов.
Батчевые задачи для крупных каталогов (10K+ товаров)
При каталогах на десятки тысяч позиций последовательные запросы неэффективны. Рекомендуемый подход:
1. Генерация списка URL
Сформируйте список URL страниц товаров (из sitemap, поиска по категориям или каталога). Разбейте на батчи по 50–100 URL.
2. Асинхронный скрейпинг с ограничением concurrency
import asyncio
import httpx
async def scrape_products(urls: list[str], session_id: str, max_concurrent: int = 5) -> list[dict]:
sem = asyncio.Semaphore(max_concurrent)
async def fetch_one(client: httpx.AsyncClient, url: str):
async with sem:
payload = {
"url": url,
"use_js_render": True,
"session_id": session_id,
"use_residential": True,
"extract_schema": product_schema
}
resp = await client.post(BASE_URL, json=payload, headers={"Authorization": f"Bearer {API_KEY}"})
resp.raise_for_status()
return resp.json().get("extract")
async with httpx.AsyncClient(timeout=90.0) as client:
tasks = [fetch_one(client, url) for url in urls]
return await asyncio.gather(*tasks)
Ограничьте max_concurrent (5–10), чтобы не провоцировать rate limits. Для очень больших каталогов рассмотрите batch-эндпоинт API: отправка массива URL, получение job_id, webhook при готовности, скачивание результата.
3. Обработка ошибок и повторные попытки
Отслеживайте 429, 503 и пустые extract. Для неудачных URL реализуйте retry с экспоненциальной задержкой. Сохраняйте прогресс, чтобы при падении можно было продолжить с последнего успешного батча.
Важные нюансы
Ограничения extract_schema
extract_schema не поддерживает все типы вложенных структур. Сложные иерархии (например, произвольное количество уровней) могут потребовать комбинации с extract_rules или постобработки. Проверяйте документацию конкретного API.
VIP TLS-профили
Для особо защищённых платформ некоторые API предлагают «VIP» TLS-профили — более редкие отпечатки, реже попадающие в блокировочные списки. Если стандартный профиль даёт высокий процент отказов, рассмотрите переход на VIP.
Надёжность networkidle
Параметр ожидания networkidle (отсутствие сетевой активности) теоретически надёжнее для SPA, но на страницах с аналитикой, чатами и бесконечным скроллом сетевая активность может не прекращаться. В таких случаях предпочтите js_wait_for с селектором конкретного элемента — это даёт более предсказуемое поведение.
Резюме
- SPA-платформы e-commerce рендерят контент через React/JavaScript — без рендеринга данные пустые
- Включайте
use_js_renderиjs_wait_forна контейнер с товарами - Используйте
extract_schemaдля устойчивого извлечения структурированных данных о товарах - Обходите rate limits через
session_idи резидентные прокси - Масштабируйте через асинхронный скрейпинг или batch API
- Учитывайте: ограничения extract_schema, VIP TLS-профили для сложных источников, выбор между networkidle и js_wait_for
InfraProxy Scraper API поддерживает JS-рендеринг, extract_schema и резидентные прокси для сбора каталогов интернет-магазинов. Узнайте условия.
Нужны надёжные прокси для вашего проекта?
InfraProxy предоставляет серверные и резидентные прокси для российского бизнеса. Договор, постоплата, техподдержка.
Читайте также
Настройка прокси для мониторинга цен конкурентов
Пошаговое руководство по настройке прокси для мониторинга цен: ротация IP, geo-targeting, sticky-сессии, обход антибот-защит. Код на Python и bash.
РуководстваКак настроить прокси для RAG-пайплайна
Практическое руководство по настройке прокси для RAG-пайплайна: архитектура, код на Python, sticky-сессии, расписание обходов. InfraProxy, SOCKS5, 100 000+ IP.
РуководстваNo-code веб-скрейпинг: извлечение данных без программирования
Как настроить сбор данных в 2026 году без написания кода: API для скрейпинга, extract_rules, автоматизация через n8n и Make.com, батчевая обработка 100+ страниц.