Скрапинг динамических сайтов
Динамические сайты загружают контент с помощью JavaScript после начальной загрузки страницы. Это руководство показывает, как собирать данные с таких сайтов с использованием browser endpoint в FourA.
Проблема
Когда вы отправляете стандартный HTTP request на сайт с активным использованием JavaScript, вы получаете базовую структуру HTML без фактического контента. Необходимые вам данные (списки товаров, цены, результаты поиска) загружаются через JavaScript после рендеринга страницы в браузере.
Это все чаще встречается в современных фреймворках, таких как React, Vue, Angular и Next.js.
Решение: запросы через браузер
Браузерный endpoint FourA (POST /api/browser/) открывает ваш URL в экземпляре браузера Chrome, который:
- Загружает страницу
- Выполняет весь JavaScript
- Ожидает рендеринга контента
- Возвращает полностью отрендеренный 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" на странице после завершения загрузки. Если элемент отсутствует, request возвращается со статусом ошибки checkText:product-grid not found, а неудачный request не тарифицируется. checkText не заставляет FourA ждать текст дольше.
Шаг 3: Парсинг HTML
Response содержит полностью отрендеренный 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 (сравните «Просмотр исходного кода» и DevTools)
- Увеличьте
timeout_ms: некоторые страницы загружаются медленно - Проверьте, требует ли страница аутентификацию или cookie (используйте параметр
cookies)
Отображается страница проверки?
- Для одиночных/HTTP-запросов переключитесь на endpoint proxy (
POST /api/proxy/) для автоматической ротации IP. - Чтобы маршрутизировать запрос браузера через proxy, передайте параметр
proxyбраузерного endpoint. Endpoint proxy оборачивает только одиночные/HTTP-запросы, но не браузерные запросы.
Параметр proxy принимает opaque ID proxy, возвращенный предыдущим ответом, а не ваш собственный адрес 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 между запросами.
Следующие шаги
- Выбор подходящего endpoint: когда использовать browser, а когда single
- Мониторинг цен конкурентов: полное руководство по отслеживанию цен
- Защищенные сайты: работа с защищенными сайтами
- Повторное использование proxy между запросами: фиксация одного выходного узла на протяжении всего сценария