Скрапинг динамических сайтов

Динамические сайты загружают контент с помощью JavaScript после первоначальной загрузки страницы. Это руководство показывает, как собирать данные с таких сайтов, используя browser endpoint от FourA.

Проблема

Когда вы отправляете стандартный HTTP request к сайту с большим количеством JavaScript, вы получаете оболочку HTML, но не сам контент. Необходимые вам данные (списки товаров, цены, результаты поиска) загружаются с помощью JavaScript после того, как страница отрендерится в браузере.

Это все чаще встречается в современных фреймворках, таких как React, Vue, Angular и Next.js.

Решение: Browser Requests

Browser endpoint от FourA (POST /api/browser/) открывает ваш URL в экземпляре браузера Chrome, который:

  1. Загружает страницу
  2. Выполняет весь JavaScript
  3. Ожидает рендеринга контента
  4. Возвращает полностью отрендеренный HTML

Шаг 1: Определите, что вам нужно

Перед выполнением request посетите целевую страницу в браузере и используйте DevTools (F12), чтобы найти фрагмент текста или элемент, который подтверждает, что контент загрузился. Например:

  • Название продукта, которое появляется после рендеринга JS
  • Класс CSS, такой как product-grid, в отрендеренном HTML
  • Текстовая строка, например "results", которая появляется только при загрузке данных

Шаг 2: Отправьте Browser Request

curl -X POST https://eu.api.foura.ai/api/browser/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
  }'

Опция checkText указывает FourA проверить наличие строки "product-grid" на отрендеренной странице. Если она не появляется до истечения таймаута, запрос завершается ошибкой, сообщая, что контент не загрузился.

Шаг 3: Парсинг HTML

Ответ содержит полностью отрендеренный HTML в поле body. Распарсите его с помощью предпочитаемой библиотеки:

Python (BeautifulSoup)

import requests
from bs4 import BeautifulSoup

resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}, json={
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
})

html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")

for product in soup.select(".product-card"):
    name = product.select_one(".product-name").text.strip()
    price = product.select_one(".product-price").text.strip()
    print(f"{name}: {price}")

Node.js (cheerio)

import * as cheerio from 'cheerio';

const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com/products',
    timeout_ms: 15000,
    checkText: 'product-grid'
  })
});

const { body: html } = await resp.json();
const $ = cheerio.load(html);

$('.product-card').each((i, el) => {
  console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});

Устранение неполадок

Все еще получаете пустой контент?

  • Убедитесь, что страница действительно использует рендеринг JavaScript (сравните "View Source" и DevTools)
  • Увеличьте timeout_ms: некоторые страницы загружаются медленно
  • Проверьте, требует ли страница аутентификации или cookie (используйте параметр cookies)

Получаете страницу с CAPTCHA?

  • Для одиночных/HTTP-запросов перейдите на proxy endpoint (POST /api/proxy/) для автоматической ротации IP.
  • Чтобы направить запрос браузера через proxy, передайте параметр proxy браузерного endpoint. Proxy endpoint оборачивает только одиночные/HTTP-запросы, а не запросы браузера.

Параметр proxy принимает непрозрачный ID proxy, который вернул предыдущий response, и никогда не принимает ваш собственный адрес proxy. Сначала выполните один вызов POST /api/proxy/ (или POST /api/auto/), прочитайте поле proxy, которое он возвращает, затем закрепите его:

# Step 1: let FourA find a working exit. The response carries "proxy": "A1B2C3".
curl -X POST "https://eu.api.foura.ai/api/proxy/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"maxTries": 5, "request": {"method": "GET", "url": "https://example.com/products"}}'

# Step 2: render through that same exit.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/products", "proxy": "A1B2C3", "timeout_ms": 20000}'

Отправка адреса вместо ID возвращает 400 Invalid proxy format. Полный паттерн описан в Повторное использование proxy между запросами.

Следующие шаги

Обновлено: 12 августа 2026 г.