Dynamische Website scrapen

Dynamische Websites laden Inhalte nach dem ersten Seitenaufruf per JavaScript nach. Diese Anleitung zeigt dir, wie du mit dem Browser-Endpoint von FourA Daten von solchen Websites erfasst.

Das Problem

Wenn du einen Standard-HTTP-Request an eine JavaScript-lastige Website sendest, erhältst du nur das HTML-Gerüst, nicht aber den eigentlichen Inhalt. Die benötigten Daten (Produktlisten, Preise, Suchergebnisse) lädt JavaScript erst nach dem Rendern der Seite im Browser nach.

Das ist bei modernen Frameworks wie React, Vue, Angular und Next.js zunehmend üblich.

Die Lösung: Browser-Requests

Der Browser-Endpoint von FourA (POST /api/browser/) öffnet deine URL in einer Chrome-Browser-Instanz, die:

  1. Die Seite lädt
  2. Sämtliches JavaScript ausführt
  3. Wartet, bis der Inhalt gerendert ist
  4. Das vollständig gerenderte HTML zurückgibt

Schritt 1: Bestimme, was du benötigst

Bevor du den Request sendest, öffne die Zielseite im Browser und nutze die DevTools (F12), um ein Textelement oder einen Selektor zu finden, der das vollständige Laden bestätigt. Zum Beispiel:

  • Ein Produktname, der erst nach dem JS-Rendering erscheint
  • Eine CSS-Klasse wie product-grid im gerenderten HTML
  • Ein Text wie "results", der nur nach dem Laden der Daten auftaucht

Schritt 2: Sende einen 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"
  }'

Die Option checkText weist FourA an zu prüfen, ob „product-grid“ nach dem Laden auf der Seite vorhanden ist. Falls nicht, schlägt der Request mit checkText:product-grid not found fehl. Ein fehlgeschlagener Request wird nicht abgerechnet. checkText führt nicht dazu, dass FourA länger auf den Text wartet.

Schritt 3: HTML parsen

Die Response enthält das vollständig gerenderte HTML im Feld body. Parse es mit deiner bevorzugten Library:

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

Fehlerbehebung

Immer noch leerer Inhalt?

  • Prüfe, ob die Seite tatsächlich JavaScript-Rendering nutzt (vergleiche „Quelltext anzeigen“ mit den DevTools)
  • Erhöhe timeout_ms: Manche Seiten laden langsam
  • Prüfe, ob die Seite Authentifizierung oder Cookies benötigt (nutze den Parameter cookies)

Erhältst du eine Verifizierungsseite?

  • Wechsle für einzelne/HTTP-Requests zum Proxy-Endpoint (POST /api/proxy/), um automatische IP-Rotation zu nutzen.
  • Um einen Browser-Request über einen Proxy zu leiten, übergib den Parameter proxy des Browser-Endpoints. Der Proxy-Endpoint verarbeitet nur einzelne/HTTP-Requests, keine Browser-Requests.

Der Parameter proxy akzeptiert die opake Proxy-ID aus einer früheren Response, niemals eine eigene Proxy-Adresse. Führe zuerst einen Aufruf von POST /api/proxy/ (oder POST /api/auto/) aus, lies das zurückgegebene Feld proxy aus und pinne es anschließend:

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

Das Senden einer Adresse anstelle einer ID wird als 400 Invalid proxy format beantwortet. Das vollständige Muster findest du unter Reuse a Proxy Across Requests.

Nächste Schritte

Aktualisiert: 27. September 2026