Scarnox · Blog

JavaScript-websites scrapen: statisch versus gerenderd

Veel moderne sites sturen een bijna leeg HTML-document en bouwen de inhoud in de browser met JavaScript. Als je scraper de pagina ophaalt en geen producten, prijzen of artikeltekst vindt, is de inhoud er wel, maar komt die later. Deze gids laat zien hoe je ziet met welk soort pagina je te maken hebt, hoe je een snellere route vindt dan een browser waar die bestaat, en hoe je gerenderde pagina's scrapet met Playwright in Python. Hij eindigt met een notitie over wat je doet wanneer een gerenderde pagina een captcha toont.

Stap 1: controleer of de inhoud in de HTML staat

Open de pagina met view-source: in je browser, of haal hem op met een gewoon HTTP-verzoek, en zoek in de bron naar een stuk tekst dat je op het scherm ziet. Drie uitkomsten komen vaak voor:

Stap 2: roep het JSON-eindpunt aan als dat bestaat

Wanneer een pagina zijn gegevens van een eindpunt ophaalt, is het rechtstreeks aanroepen van dat eindpunt meestal de beste optie. Het is kleiner, sneller en stabieler dan de gerenderde pagina. Kopieer de request-URL, controleer welke headers de site vereist, en probeer het vanuit een script. Doe dit alleen waar de voorwaarden van de site het toestaan, en respecteer eventuele snelheidslimieten of authenticatie die de site verwacht. Een niet-gedocumenteerd eindpunt kan zonder waarschuwing veranderen, dus schrijf je parser zo dat hij hard faalt wanneer de vorm van het antwoord verandert.

Stap 3: render de pagina wanneer het moet

Als de inhoud echt de browser nodig heeft, stuur dan een headless browser aan. Playwright is een goede keuze voor Python. Het onderstaande voorbeeld opent een productoverzicht, wacht tot de inhoud verschijnt, en leest de tekst van elke kaart:

from playwright.sync_api import sync_playwright

URL = "https://example.com/products"  # een pagina die je mag scrapen

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto(URL, wait_until="domcontentloaded", timeout=60_000)
    # Wacht op het element dat bewijst dat de gegevens zijn aangekomen.
    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)

Wachten op een specifieke selector is veel betrouwbaarder dan een vaste sleep. Een vaste pauze is op een trage dag te kort, en op een snelle dag verspilt die tijd. Kies het element dat pas verschijnt wanneer de gegevens zijn geladen.

Stap 4: behandel oneindig scrollen en paginering

Sommige pagina's laden meer items wanneer je scrolt. Scroll naar beneden, wacht tot het aantal items groeit, en stop wanneer het niet meer groeit. Pagina's met genummerde paginering zijn eenvoudiger: zoek de link naar de volgende pagina, volg hem, en stop bij de laatste pagina. Stel altijd een maximum aantal pagina's of scrolls in, zodat een bug je crawler nooit eindeloos laat draaien.

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)  # geef de volgende batch tijd om te laden
    return previous

Stap 5: houd de browser zuinig

Rendering is duur. Blokkeer afbeeldingen, lettertypen en media die je niet nodig hebt, en hergebruik één browser voor veel pagina's in plaats van elke keer een nieuwe te starten. Sluit pagina's en contexten wanneer je klaar bent, zodat het geheugen niet oploopt tijdens een lange run.

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

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

Stap 6: wanneer een gerenderde pagina een captcha toont

Soms toont de gerenderde pagina een captcha voordat hij inhoud laat zien. Als dat captcha PopularCaptcha is, het live captchatype bij Scarnox, lees je de sitekey van de pagina, vraag je een token aan en plaats je het token in het formulierveld dat de site verwacht. De PopularCaptcha-gids voor Python loopt die stap door. Andere widgets zijn nog niet live, dus bekijk captchatypen uitgelegd voordat je ergens op vooruit plant.

Wees voorzichtig met de browser zelf. Een headless browser die duidelijk geautomatiseerd oogt, kan meer controles uitlokken, niet minder. Lees headless browserdetectie voor de signalen om op te letten, en geef de voorkeur aan langzamere en minder paginaladingen.

Scrape verantwoord

Volgende stappen

Start met gratis proefkrediet, zonder creditcard: maak een account aan en test de PopularCaptcha-flow op een pagina die van jou is. Voor de actuele tarieven zie de prijspagina.