Zalando ist einer der größten Modehändler in Europa, und seine öffentlichen Produktseiten tragen genau die strukturierten Daten, die Preisüberwachung, Sortimentsverfolgung und Modetrendforschung antreiben: Produktnamen, Marken, Preise, verfügbare Größen und Farben. Das Problem ist, dass Zalando diese Seiten mit JavaScript rendert und sich stark gegen Bots wehrt, sodass eine einfache HTTP-Anfrage eine leere Hülle oder eine Challenge-Seite anstelle des angestrebten Katalogs liefert.

Dieser Leitfaden zeigt Ihnen, wie Sie einen Zalando-Scraper in Python auf zuverlässige Weise erstellen. Sie rufen vollständig gerenderte Produktseiten über die Crawling API mit dem JavaScript-Token ab, parsen das Markup mit BeautifulSoup und extrahieren die relevanten Felder. Wir beschränken den gesamten Walkthrough auf öffentliche Produktdaten, und der Abschnitt zur Rechtslage gegen Ende ist kein Boilerplate, lesen Sie ihn daher, bevor Sie dies auf ein echtes Volumen anwenden.

Was Sie erstellen werden

Ein Python-Skript, das eine öffentliche Zalando-Produkt-URL entgegennimmt, das gerenderte HTML über die Crawling API abruft und einen strukturierten Datensatz des Artikels extrahiert. Wir verwenden eine einzelne Produktseite als durchgehendes Beispiel und ziehen diese Felder heraus:

  • Produktname der Titel des Artikels, zum Beispiel "Leather Handbag".
  • Marke das Label hinter dem Produkt, wie "Zign".
  • Preis der aktuelle Verkaufspreis einschließlich Währung.
  • Verfügbare Größen die auf der Seite als vorrätig angezeigten Größen.
  • Farbe die Farbgebung der aufgelisteten Variante.

Sobald eine Seite funktioniert, schleifen wir über eine Liste von Produkt-URLs und paced die Anfragen, damit ein echter Job gesund bleibt. Der Modekatalog ist ein klassisches E-Commerce-Web-Scraping-Ziel, und das hier verwendete Muster überträgt sich auf die meisten Händler.

Warum ein einfacher Abruf bei Zalando scheitert

Wenn Sie eine Zalando-Produkt-URL mit einem einfachen HTTP-Client anfordern, erhalten Sie eine von zwei unnötigen Antworten: einen Status 200 mit fast keinen Produktdaten im Body oder eine Bot-Challenge. Zwei Dinge arbeiten gegen Sie. Erstens rendert Zalando seinen Produktinhalt im Browser mit JavaScript, sodass das anfängliche HTML eine Hülle ist, die sich erst nach dem Ausführen der Seitenskripte füllt. Zweitens kennzeichnet Zalando automatisierten Traffic schnell: Datacenter-IPs und Anfragemuster, die nicht wie ein echter Browser aussehen, werden herausgefordert oder blockiert, bevor sie jemals den gerenderten Inhalt erreichen.

Ein funktionierender Zalando-Scraper benötigt also zwei Dinge in einer Anfrage: einen Browser, der die Seite tatsächlich rendert, und eine IP, die die Plattform als echten Besucher liest. Sie können das selbst mit einem Headless-Browser plus einem Pool rotierender Residential-Proxys zusammenstellen, aber diese zu verknüpfen und funktionsfähig zu halten, ist der Großteil der Arbeit. Die Crawling API kombiniert beides in einem einzigen Aufruf: Sie senden die URL mit einem JavaScript-Token, sie rendert die Seite hinter einer vertrauenswürdigen IP und gibt fertiges HTML zurück, das Sie parsen können. Wenn Sie den Hintergrund dazu möchten, warum clientseitiges Rendering naive Scraper scheitern lässt, lesen Sie wie man JavaScript-Websites crawlt.

Warum der JS-Token

Crawlbase bietet zwei Token-Typen an. Der normale Token ruft statisches HTML ab; der JavaScript-Token (JS) rendert die Seite zuerst in einem echten Browser. Zalando ist clientseitig gerendert, daher benötigen Sie hier den JS-Token. Die Verwendung des normalen Tokens gibt dieselbe leere Hülle zurück, die ein einfacher Abruf liefern würde, und es gibt darin nichts Nützliches zu parsen.

Voraussetzungen

Sie benötigen einige Dinge, bevor Sie Code schreiben können. Keines davon dauert lange.

Grundlegendes Python. Sie sollten in der Lage sein, ein Python-Skript zu schreiben, auszuführen und Pakete mit pip zu installieren. Wenn BeautifulSoup neu für Sie ist, deckt unser Leitfaden zu BeautifulSoup in Python die Parse-Grundlagen ab, die dieses Tutorial voraussetzt.

Python 3.8 oder höher. Überprüfen Sie Ihre Version mit python --version. Wenn Sie es nicht haben, installieren Sie es von python.org oder über eine Distribution wie Anaconda.

Ein Crawlbase-Konto und JS-Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihren JavaScript-Token (JS) von der Kontodokumentationsseite. Behandeln Sie den Token wie ein Passwort: Er authentifiziert Ihre Anfragen, halten Sie ihn also aus der Versionskontrolle heraus.

Projekt einrichten

Erstellen Sie eine virtuelle Umgebung, damit Projektabhängigkeiten isoliert bleiben, und installieren Sie dann die zwei Bibliotheken, die der Scraper benötigt.

bash
python --version

python -m venv zalando_env
source zalando_env/bin/activate

pip install crawlbase beautifulsoup4

Aktivieren Sie unter Windows die Umgebung mit zalando_env\Scripts\activate anstelle der source-Zeile. Zwei Abhängigkeiten erledigen die Arbeit: crawlbase ist der offizielle Client für die Crawling API, und beautifulsoup4 parst das zurückgegebene HTML, sodass Sie einzelne Felder per CSS-Selektor herausziehen können.

Schritt 1: Die gerenderte Produktseite abrufen

Beginnen Sie damit, die fertige Seite zu laden. Importieren Sie die CrawlingAPI-Klasse, initialisieren Sie sie mit Ihrem JS-Token und fordern Sie die Produkt-URL an. Die Überprüfung des Statuscodes vor dem Parsen macht Fehler laut statt still.

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"})

def crawl(page_url):
    options = {"ajax_wait": "true", "page_wait": 5000}
    response = api.get(page_url, options)
    if response["status_code"] == 200:
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['status_code']}")
    return None

if __name__ == "__main__":
    page_url = "https://en.zalando.de/zign-handbag-black-zi151h08a-q11.html"
    html = crawl(page_url)
    print(html[:500] if html else "No HTML returned")

Die zwei Wartoptionen sind bei einem clientseitig gerenderten Ziel wie diesem wichtig. ajax_wait teilt der API mit, auf das Laden asynchroner Inhalte zu warten, und page_wait hält für eine feste Anzahl von Millisekunden nach dem Laden an, damit spät gerenderte Elemente erscheinen, bevor die Seite erfasst wird. Fünf Sekunden sind ein vernünftiger Ausgangspunkt; erhöhen Sie diesen Wert, wenn die Produktfelder leer zurückkommen. Führen Sie das Skript mit python scraper.py aus und Sie sollten echtes Produkt-Markup sehen, nicht die leere Hülle, die ein einfacher Abruf zurückgibt. Das bestätigt, dass das Rendering funktioniert, bevor Sie einen einzigen Selektor schreiben.

Crawlbase Crawling API

Zalando benötigt eine gerenderte Seite hinter einer vertrauenswürdigen IP in einem einzigen Aufruf. Die Crawling API nimmt einen JS-Token, führt die Seite in einem echten Browser aus, rotiert serverseitig durch Residential-IPs und gibt Ihnen fertiges HTML, sodass Sie selbst keine Headless-Fleet und keinen Proxy-Pool betreiben müssen. Testen Sie es zuerst auf einer öffentlichen Produktseite im kostenlosen Kontingent.

Schritt 2: Produktfelder mit BeautifulSoup parsen

Mit dem gerenderten HTML in der Hand laden Sie es in BeautifulSoup und ziehen jedes Feld anhand seines Selektors heraus. Zalando-Produktseiten legen die Kerndaten in einer ziemlich vorhersehbaren Struktur an, sodass Sie Name, Marke, Preis, Größen und Farbe einzelnen Selektoren zuordnen können. Kapseln Sie die Extraktion in Hilfsfunktionen, damit ein fehlendes Feld nicht den Lauf zum Absturz bringt.

python
from bs4 import BeautifulSoup

def text_of(soup, selector):
    el = soup.select_one(selector)
    return el.get_text(strip=True) if el else None

def all_text(soup, selector):
    return [el.get_text(strip=True) for el in soup.select(selector)]

def scrape_product(html):
    soup = BeautifulSoup(html, "html.parser")

    sizes = all_text(soup, "[data-testid='pdp-size-picker'] [role='option']")

    return {
        "name": text_of(soup, "span.EKabf7.R_QwOV"),
        "brand": text_of(soup, "span.OBkCPz.Z82GLX"),
        "price": text_of(soup, "span.voFjEy.Km7l2y"),
        "color": text_of(soup, "[data-testid='color-name']"),
        "sizes": [s for s in sizes if s],
    }

Die Hilfsfunktion text_of macht zwei nützliche Dinge gleichzeitig: Sie fragt ein einzelnes Element ab und gibt None zurück, wenn das Element fehlt, anstatt bei einem .get_text()-Aufruf gegen nichts zu werfen. Die Hilfsfunktion all_text sammelt jede Übereinstimmung für Felder, die sich wiederholen, was Sie für die Größenoptionen wollen. Das hält die Extraktion widerstandsfähig, wenn ein Feld auf einer gegebenen Seite fehlt, was häufig vorkommt, da nicht jedes Produkt alle Details auflistet.

Selektoren driften

Zalandos Klassennamen (die gehashten Token wie EKabf7 und voFjEy) sind generiert und ändern sich ohne Vorankündigung. Behandeln Sie die obigen Selektoren als Startvorlage, nicht als Vertrag. Wenn ein Feld als None oder als leere Liste zurückkommt, überprüfen Sie die Live-Seite in den Entwicklertools Ihres Browsers und aktualisieren Sie den Selektor. Die stabilen data-testid-Attribute überleben tendenziell länger als die gehashten Klassennamen, bevorzugen Sie diese also, wo sie existieren. Regelmäßige Selektor-Wartung ist für jeden produktiven Scraper normal, kein Zeichen dafür, dass etwas kaputt ist.

Schritt 3: Alles zusammenfügen

Verbinden Sie jetzt den Abruf und das Parsen in einem lauffähigen Skript. Rufen Sie das gerenderte HTML ab, übergeben Sie es an den Parser und geben Sie den strukturierten Datensatz aus.

python
import json
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"})

def crawl(page_url):
    options = {"ajax_wait": "true", "page_wait": 5000}
    response = api.get(page_url, options)
    if response["status_code"] == 200:
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['status_code']}")
    return None

def text_of(soup, selector):
    el = soup.select_one(selector)
    return el.get_text(strip=True) if el else None

def all_text(soup, selector):
    return [el.get_text(strip=True) for el in soup.select(selector)]

def scrape_product(html):
    soup = BeautifulSoup(html, "html.parser")
    sizes = all_text(soup, "[data-testid='pdp-size-picker'] [role='option']")
    return {
        "name": text_of(soup, "span.EKabf7.R_QwOV"),
        "brand": text_of(soup, "span.OBkCPz.Z82GLX"),
        "price": text_of(soup, "span.voFjEy.Km7l2y"),
        "color": text_of(soup, "[data-testid='color-name']"),
        "sizes": [s for s in sizes if s],
    }

def main():
    page_url = "https://en.zalando.de/zign-handbag-black-zi151h08a-q11.html"
    html = crawl(page_url)
    if not html:
        return
    data = scrape_product(html)
    print(json.dumps(data, indent=2, ensure_ascii=False))

if __name__ == "__main__":
    main()

Das Setzen von ensure_ascii=False beim JSON-Dump hält das Euro-Zeichen und akzentuierte Zeichen lesbar, anstatt sie zu escapen. Führen Sie das vollständige Skript mit python scraper.py aus und Sie erhalten einen sauberen strukturierten Datensatz für das Produkt.

Wie die Ausgabe aussieht

Das Skript gibt einen einzelnen Datensatz aus, der in JSON, CSV oder eine Datenbank geschrieben werden kann.

json
{
  "name": "LEATHER - Handbag",
  "brand": "Zign",
  "price": "49,99 €",
  "color": "black",
  "sizes": ["One Size"]
}

Für ein Bekleidungsartikel würde die sizes-Liste die tatsächliche Größenreihe enthalten, zum Beispiel ["XS", "S", "M", "L"], mit ausverkauften Größen, die herausgefiltert wurden, wenn Sie den Verfügbarkeitsstatus des Größenauswählers filtern.

Skalierung auf viele Produkte

Eine Seite ist eine Demo; ein echter Job läuft über eine Liste von Produkten. Die Form bleibt dieselbe: Halten Sie eine Liste von Produkt-URLs, rufen Sie jede über die Crawling API ab, parsen Sie sie mit derselben Funktion und sammeln Sie die Zeilen. Da jede Produktseite dieselbe Struktur hat, funktioniert der bereits geschriebene Parser für alle ohne Änderungen. Die wichtigste Ergänzung ist das Pacing: Eine kurze Pause zwischen Anfragen verhindert, dass der Lauf wie ein Schwall von Bot-Traffic aussieht.

python
import time

products = [
    "https://en.zalando.de/zign-handbag-black-zi151h08a-q11.html",
    "https://en.zalando.de/anna-field-handbag-black-an651h0x2-q11.html",
]

results = []
for url in products:
    html = crawl(url)
    if html:
        results.append({"url": url, **scrape_product(html)})
    time.sleep(2)

with open("zalando_products.json", "w", encoding="utf-8") as f:
    json.dump(results, f, indent=2, ensure_ascii=False)

Um Produkt-URLs im Maßstab zu finden, scrapen Sie Zalandos öffentliche Katalogseiten (zum Beispiel https://en.zalando.de/catalogue/?q=handbags) mit demselben Abruf-dann-Parse-Muster, sammeln Sie die Produkt-Links und besuchen Sie dann jede Seite. Halten Sie das Volumen dabei vernünftig und respektieren Sie die weiter unten beschriebenen Ratenbeschränkungen. Wenn Preis Ihr Endziel ist, fließen die gesammelten Datensätze direkt in eine Preisintelligenz-Pipeline.

Entsperrt bleiben

Selbst mit gehandhabtem Rendering beobachtet Zalando Scraper-ähnlichen Traffic. Einige Gewohnheiten halten einen Lauf gesund, und sie gelten für jedes schwierige kommerzielle Ziel.

  • Pacing Ihrer Anfragen. Seiten in einer engen Schleife zu hämmern ist der schnellste Weg, gedrosselt zu werden. Das time.sleep oben verteilt Anfragen; variieren Sie Ihre Ziele, anstatt einen Pfad mit voller Geschwindigkeit zu crawlen.
  • Auf Rotation setzen. Ein Pool von Residential-IPs verteilt Anfragen auf viele echte Nutzeradressen, sodass keine einzelne ein Ratenlimit auslöst. Die Crawling API übernimmt das für Sie; wenn Sie Ihren eigenen Stack verwenden, ist dies der Teil, den Sie richtig machen müssen.
  • Statuscodes lesen. Ein Lauf, der beginnt, Herausforderungen oder Fehler zurückzugeben, signalisiert Ihnen, dass die aktuelle Rate oder IP-Tier nicht mehr ausreicht. Behandeln Sie das als Signal zum Zurückhalten, nicht als Rauschen zum Ignorieren.

Für das breitere Vorgehen lesen Sie wie man Websites ohne Blockierung scrapt und den tieferen Einblick in das Umgehen von CAPTCHAs beim Web Scraping. Wenn Sie Ihren eigenen Traffic lieber durch einen rotierenden Pool leiten möchten, anstatt die verwaltete API zu verwenden, gibt Ihnen der Smart AI Proxy (auch als AI Proxy bekannt) dieselbe Residential-IP-Rotation als Drop-in-Proxy-Endpunkt. Derselbe Ansatz erstreckt sich auf benachbarte Kataloge wie AliExpress und Walmart.

Ob das Scrapen von Zalando erlaubt ist, hängt von Zalandos Nutzungsbedingungen, Ihrer Gerichtsbarkeit und dem ab, was Sie mit den Daten tun. Zalandos Bedingungen schränken den automatisierten Zugriff ein, sodass das Scrapen unabhängig von der Sorgfalt Ihres Werkzeugs gegen diese Bedingungen verstoßen kann. Keiner der hier aufgeführten Codes ändert das; er macht nur den technischen Teil funktionsfähig. Lesen Sie Zalandos Nutzungsbedingungen und die robots.txt und behandeln Sie beide als Grenze für das, was Sie sammeln.

Einige Leitlinien, die es wert sind, einzuhalten: Sammeln Sie nur öffentliche Produktdaten: Produktname, Marke, Preis, verfügbare Größen und Farbe, die jeder ohne ein Konto sehen kann. Respektieren Sie Zalandos angegebene Ratenerwartungen und halten Sie Ihr Anfragevolumen so niedrig, dass Sie seine Server nicht belasten. Vermeiden Sie personenbezogene Daten, einschließlich allem, was mit identifizierbaren Personen wie Rezensenten-Profilen oder Kontoinformationen verbunden ist. Wenn Sie die Daten kommerziell weiterverwenden möchten, holen Sie sich Erlaubnis oder eine offizielle Vereinbarung, anstatt Stillschweigen als Zustimmung zu betrachten.

Dieser Leitfaden ist bewusst auf öffentliche Produktseiten beschränkt, weil das die Grenze ist, die die Arbeit vertretbar macht. Er deckt nichts hinter einem Login, Konto- oder Bestelldaten, personenbezogene Daten, login-gesperrte Seiten oder Versuche, die Authentifizierung zu umgehen, nicht ab. Für groß angelegte oder kommerzielle Nutzung bevorzugen Sie eine offizielle API oder eine Datenvereinbarung mit Zalando gegenüber einem ausgefeiltererem Scraper. Nur öffentliche Produktdaten ist die Regel, die Sie auf der richtigen Seite beider Bedingungen und des Gesetzes hält.

Zusammenfassung

Wichtigste Erkenntnisse

  • Zalando ist clientseitig gerendert. Ein einfacher Abruf gibt eine leere Hülle oder eine Challenge zurück, sodass Sie die Seite rendern müssen, bevor Sie sie parsen.
  • Sie benötigen Rendering und eine vertrauenswürdige IP zusammen. Die Crawling API mit einem JS-Token macht beides in einem Aufruf; ajax_wait und page_wait steuern, wie lange sie auf Inhalte wartet.
  • BeautifulSoup übernimmt die Extraktion. Ordnen Sie Produktname, Marke, Preis, Größen und Farbe aktuellen Selektoren zu, bevorzugen Sie stabile data-testid-Attribute und rechnen Sie damit, dass die gehashten Klassennamen driften.
  • Skalieren Sie durch das Schleifen von URLs mit Pacing. Derselbe Parser funktioniert für jedes Produkt, sodass ein echter Job nur eine Liste von Links plus eine kurze Pause zwischen Anfragen ist.
  • Bleiben Sie bei öffentlichen Daten. Respektieren Sie Zalandos ToS und robots.txt, bevorzugen Sie eine offizielle API für Bulk- oder kommerzielle Nutzung und berühren Sie niemals Konten, login-gesperrte Seiten oder personenbezogene Informationen.

Häufig gestellte Fragen

Warum gibt ein einfacher Abruf keine Daten von Zalando zurück?

Weil Zalando seinen Produktinhalt clientseitig mit JavaScript rendert. Das anfängliche HTML ist eine Hülle, die sich erst füllt, nachdem die Seitenskripte in einem Browser ausgeführt wurden, sodass eine rohe HTTP-Anfrage Status 200 mit leeren Produktfeldern zurückgibt oder stattdessen eine Bot-Challenge. Um echte Daten zu erhalten, müssen Sie die Seite zuerst rendern, was der JS-Token der Crawling API für Sie übernimmt.

Benötige ich den normalen Token oder den JS-Token für Zalando?

Den JS-Token. Der normale Token ruft statisches HTML ab, das auf Zalando dieselbe leere Hülle ist, die ein einfacher Abruf zurückgibt. Der JS-Token rendert die Seite zuerst in einem echten Browser, sodass Produktname, Marke, Preis, Größen und Farbe vorhanden sind, wenn BeautifulSoup sie parst.

Meine Selektoren geben None oder leere Listen zurück. Was hat sich geändert?

Mit großer Wahrscheinlichkeit Zalandos Markup. Seine gehashten Klassennamen wie EKabf7 und voFjEy sind generiert und ändern sich ohne Vorankündigung, sodass letzte Woche funktionierende Selektoren brechen können. Überprüfen Sie eine Live-Produktseite in den Entwicklertools Ihres Browsers und aktualisieren Sie die Selektoren. Bevorzugen Sie die stabilen data-testid-Attribute, wo sie existieren, da diese Redesigns länger überleben als die gehashten Klassen.

Kann ich Python anstelle von Puppeteer oder Node.js verwenden, um Zalando zu scrapen?

Ja. Da die Crawling API die Seite serverseitig rendert und fertiges HTML zurückgibt, müssen Sie überhaupt keinen Headless-Browser lokal ausführen. Ein kleines Python-Skript mit dem crawlbase-Client und BeautifulSoup reicht aus, was der gesamte Ansatz in diesem Leitfaden ist. Das hält den Scraper leicht und einfach zu planen.

Wie scrapt man viele Zalando-Produkte, ohne blockiert zu werden?

Halten Sie Ihre IP-bezogene Anfragerate niedrig, fügen Sie eine kurze Pause zwischen Anfragen hinzu und variieren Sie Ihre Ziele, anstatt einen Pfad zu schleifen. Routen Sie über rotierende Residential-IPs, sodass keine einzelne Adresse ein Ratenlimit auslöst; die Crawling API verwaltet die Rotation und einen vertrauenswürdigen IP-Pool für Sie. Beobachten Sie die Statuscodes und halten Sie inne, wenn Sie beginnen, Herausforderungen zu sehen.

Das hängt von Zalandos Nutzungsbedingungen, Ihrer Gerichtsbarkeit und Ihrer Nutzung der Daten ab. Dieser Leitfaden bleibt bei öffentlichen Produktdaten (Name, Marke, Preis, Größen, Farbe) und bittet Sie, robots.txt und die ToS zu respektieren. Er deckt Kontodaten, personenbezogene Daten, login-gesperrte Seiten oder das Umgehen der Authentifizierung nicht ab. Für Bulk- oder kommerzielle Nutzung ist eine offizielle API oder eine Datenvereinbarung der richtige Weg, kein Scraper.

Jetzt loslegen

Crawlen Sie jede Website im großen Maßstab, ohne gegen die Infrastruktur zu kämpfen.

Crawlbase übernimmt Proxys, Fingerprints und CAPTCHAs, damit Ihr Team Datenpipelines ausliefert, statt Crawl-Infrastruktur zu pflegen. 1.000 Anfragen kostenlos, keine Karte erforderlich.

Self-Service · Kein Verkaufsgespräch erforderlich · Enterprise-Crawl-Volumen verfügbar