Scrapowanie dynamicznych stron

Dynamiczne strony internetowe ładują treść za pomocą JavaScript po początkowym załadowaniu strony. Ten poradnik pokazuje, jak pobierać dane z takich witryn przy użyciu endpointu przeglądarkowego FourA.

Problem

Gdy wysyłasz standardowe request HTTP do witryny intensywnie korzystającej z JavaScript, otrzymujesz szkielet HTML, ale bez właściwej treści. Potrzebne dane (listy produktów, ceny, wyniki wyszukiwania) są ładowane przez JavaScript dopiero po wyrenderowaniu strony w przeglądarce.

Jest to coraz powszechniejsze w nowoczesnych frameworkach, takich jak React, Vue, Angular i Next.js.

Rozwiązanie: Requesty przeglądarkowe

Endpoint przeglądarkowy FourA (POST /api/browser/) otwiera Twój URL w instancji przeglądarki Chrome, która:

  1. Ładuje stronę
  2. Wykonuje cały kod JavaScript
  3. Czeka na wyrenderowanie treści
  4. Zwraca w pełni wyrenderowany HTML

Krok 1: Określ, czego potrzebujesz

Przed wysłaniem requestu otwórz docelową stronę w przeglądarce i użyj DevTools (F12), aby znaleźć fragment tekstu lub element potwierdzający załadowanie treści. Na przykład:

  • Nazwę produktu, która pojawia się po wyrenderowaniu JS
  • Klasę CSS, taką jak product-grid w wyrenderowanym HTML
  • Ciąg tekstowy, taki jak "results", który pojawia się dopiero po załadowaniu danych

Krok 2: Wyślij request przeglądarkowy

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"
  }'

Opcja checkText instruuje FourA, aby sprawdzić, czy "product-grid" znajduje się na stronie po zakończeniu jej ładowania. Jeśli go nie ma, żądanie kończy się błędem checkText:product-grid not found, a nieudane żądanie nie podlega opłacie. checkText nie wydłuża czasu oczekiwania FourA na tekst.

Krok 3: Parsowanie HTML

Odpowiedź zawiera w pełni wyrenderowany HTML w polu body. Przetwórz go za pomocą wybranej biblioteki:

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());
});

Rozwiązywanie problemów

Nadal otrzymujesz pustą zawartość?

  • Sprawdź, czy strona faktycznie wymaga renderowania JavaScript (porównaj "Pokaż źródło strony" z DevTools)
  • Zwiększ timeout_ms: niektóre strony ładują się wolniej
  • Sprawdź, czy strona wymaga uwierzytelnienia lub plików cookies (użyj parametru cookies)

Pojawia się strona weryfikacji?

  • W przypadku pojedynczych requestów HTTP przełącz się na endpoint proxy (POST /api/proxy/), aby korzystać z automatycznej rotacji IP.
  • Aby przekierować request przeglądarki przez proxy, przekaż parametr proxy w endpoincie przeglądarki. Endpoint proxy obsługuje wyłącznie pojedyncze requesty HTTP, a nie sesje przeglądarki.

Parametr proxy przyjmuje identyfikator proxy zwrócony we wcześniejszej odpowiedzi, a nie własny adres proxy. Wykonaj najpierw jedno wywołanie POST /api/proxy/ (lub POST /api/auto/), odczytaj zwrócone pole proxy, a następnie przypnij je:

# 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}'

Wysłanie adresu zamiast identyfikatora zwraca błąd 400 Invalid proxy format. Pełny wzorzec znajduje się w sekcji Reuse a Proxy Across Requests.

Następne kroki

Aktualizacja: 27 września 2026