Scarnox · Blog

JavaScript-gerenderte Websites scrapen: so geht's

Viele moderne Websites senden ein fast leeres HTML-Dokument und bauen den Inhalt im Browser mit JavaScript auf. Wenn dein Scraper die Seite abruft und keine Produkte, keine Preise und keinen Artikeltext findet, ist der Inhalt da, kommt aber später. Dieser Leitfaden zeigt, wie du erkennst, mit welcher Art Seite du es zu tun hast, wie du dort, wo es einen gibt, einen schnelleren Weg als einen Browser findest und wie du gerenderte Seiten mit Playwright in Python scrapst. Am Ende steht ein Hinweis dazu, was zu tun ist, wenn eine gerenderte Seite ein Captcha zeigt.

Schritt 1: Prüfen, ob der Inhalt im HTML steht

Öffne die Seite mit view-source: in deinem Browser oder rufe sie mit einer einfachen HTTP-Anfrage ab, und durchsuche den Quelltext nach einem Textstück, das du auf dem Bildschirm siehst. Drei Ergebnisse sind häufig:

Schritt 2: Den JSON-Endpunkt aufrufen, wenn es einen gibt

Wenn eine Seite ihre Daten von einem Endpunkt holt, ist es meist die beste Option, diesen Endpunkt direkt aufzurufen. Er ist kleiner, schneller und stabiler als die gerenderte Seite. Kopiere die Anfrage-URL, prüfe, welche Header die Seite verlangt, und probiere es aus einem Skript. Tu das nur, wenn die Nutzungsbedingungen der Seite es erlauben, und respektiere Ratenlimits oder Authentifizierung, die die Seite erwartet. Ein nicht dokumentierter Endpunkt kann sich ohne Vorankündigung ändern, deshalb sollte dein Parser laut scheitern, wenn sich die Form der Antwort ändert.

Schritt 3: Die Seite rendern, wenn es nötig ist

Wenn der Inhalt wirklich den Browser braucht, steuere einen Headless-Browser. Playwright ist eine gute Wahl für Python. Das folgende Beispiel öffnet eine Produktliste, wartet, bis der Inhalt erscheint, und liest den Text jeder Karte aus:

from playwright.sync_api import sync_playwright

URL = "https://example.com/products"  # eine Seite, die du scrapen darfst

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto(URL, wait_until="domcontentloaded", timeout=60_000)
    # Auf das Element warten, das belegt, dass die Daten angekommen sind.
    page.wait_for_selector(".product-card", timeout=30_000)
    titles = page.locator(".product-card h2").all_inner_texts()
    browser.close()

for title in titles:
    print(title)

Auf einen bestimmten Selektor zu warten ist weit zuverlässiger als ein festes sleep. Eine feste Pause ist entweder an einem langsamen Tag zu kurz oder kostet an einem schnellen Tag unnötig Zeit. Wähle das Element, das erst erscheint, wenn die Daten geladen sind.

Schritt 4: Endloses Scrollen und Paginierung behandeln

Manche Seiten laden beim Scrollen weitere Einträge nach. Scrolle bis unten, warte, bis die Anzahl der Einträge wächst, und höre auf, wenn sie nicht mehr wächst. Seiten mit nummerierter Paginierung sind einfacher: Finde den Link zur nächsten Seite, folge ihm und stoppe bei der letzten Seite. Setze immer eine maximale Anzahl an Seiten oder Scroll-Vorgängen, damit ein Fehler deinen Crawler nicht ewig laufen lässt.

def scroll_until_done(page, selector: str, max_rounds: int = 20) -> int:
    previous = -1
    for _ in range(max_rounds):
        count = page.locator(selector).count()
        if count == previous:
            break
        previous = count
        page.mouse.wheel(0, 4000)
        page.wait_for_timeout(1500)  # dem nächsten Stapel Zeit zum Laden geben
    return previous

Schritt 5: Den Browser sparsam einsetzen

Rendern ist teuer. Blockiere Bilder, Schriften und Medien, die du nicht brauchst, und verwende einen Browser für viele Seiten, statt bei jeder einen neuen zu starten. Schließe Seiten und Kontexte, wenn du fertig bist, damit der Speicherverbrauch bei einem langen Lauf nicht steigt.

def block_heavy_assets(route):
    if route.request.resource_type in ("image", "font", "media"):
        route.abort()
    else:
        route.continue_()

page.route("**/*", block_heavy_assets)

Schritt 6: Wenn eine gerenderte Seite ein Captcha zeigt

Manchmal zeigt die gerenderte Seite ein Captcha, bevor sie Inhalte zeigt. Wenn dieses Captcha PopularCaptcha ist, der aktuell live verfügbare Captcha-Typ bei Scarnox, liest du den Sitekey von der Seite, forderst ein Token an und legst das Token in das Formularfeld, das die Seite erwartet. Der PopularCaptcha-Python-Leitfaden führt durch diesen Schritt. Andere Widgets sind noch nicht live, prüfe daher Captcha-Typen erklärt, bevor du mit einem davon planst.

Sei vorsichtig mit dem Browser selbst. Ein Headless-Browser, der eindeutig automatisiert wirkt, kann mehr Prüfungen auslösen, nicht weniger. Lies Headless-Browser-Erkennung für die Signale, auf die du achten solltest, und bevorzuge langsamere Seitenaufrufe in geringerer Anzahl.

Verantwortungsvoll scrapen

Nächste Schritte

Starte mit kostenlosem Testguthaben, ohne Karte: Konto erstellen und teste den PopularCaptcha-Ablauf auf einer Seite, die dir gehört. Aktuelle Preise findest du auf der Preisseite.