Wie man Zillow-Immobiliendaten scrapt: Search JSON, Zestimate, PerimeterX

Zillow liefert seine Listendaten als JSON, versteckt auf der Seite — Sie müssen nie ein einziges div parsen. So steuern Sie die Map-Bounds-Such-API, umgehen das Paginierungslimit und überstehen PerimeterX.

Zillow verfügt über mehr als 110 Millionen Immobilien und zieht rund 245 Millionen monatliche Besucher an, was es zur Standardquelle für US-Immobiliendaten macht — Preise, Adressen, Betten, Bäder, Zestimates und Mietschätzungen. Es steht auch hinter PerimeterX und rendert clientseitig, sodass naive Scraper einen 403 und eine leere Seite erhalten. Die gute Nachricht: Zillow liefert Ihnen seine Daten als JSON, wenn Sie wissen, wo Sie suchen müssen, und seine Suche wird durch Kartenkoordinaten gesteuert, die Sie direkt aufrufen können. Hier ist der gesamte Ansatz.

Parsen Sie kein HTML — Zillow liefert JSON

Es ist nicht nötig, sich mit CSS-Selektoren auf einer Zillow-Immobilienseite herumzuschlagen. Der vollständige Immobilien-Datensatz ist als versteckte Webdaten in einem Script-Tag eingebettet. Zwei Orte decken fast jede Seite ab: <script id="__NEXT_DATA__"> enthält den Next.js-Cache, und einige Seiten verwenden stattdessen <script id="hdpApolloPreloadedData"> (den Apollo GraphQL-Cache). Greifen Sie auf eines davon zu, parsen Sie es, und Sie haben ein sauberes Objekt mit zpid, price, livingArea, bedrooms, bathrooms, latLong, homeStatus, rentZestimate und mehr:

import json, re, requests

proxy = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": proxy, "https": proxy}
HEADERS = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
           "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36",
           "accept-language": "en-US,en;q=0.9"}

def property_json(url):
    r = requests.get(url, headers=HEADERS, proxies=proxies, timeout=20)
    r.raise_for_status()                       # 403 => blocked, rotate IP
    m = re.search(r'id="__NEXT_DATA__"[^>]*>(.*?)</script>', r.text, re.S)
    if m:
        data = json.loads(m.group(1))
        cache = data["props"]["pageProps"]["componentProps"]["gdpClientCache"]
        return next(iter(json.loads(cache).values()))["property"]
    # fallback: Apollo cache
    m = re.search(r'id="hdpApolloPreloadedData"[^>]*>(.*?)</script>', r.text, re.S)
    cache = json.loads(json.loads(m.group(1))["apiCache"])
    return next(v["property"] for k, v in cache.items() if "ForSale" in k)

Der eingebettete Datensatz ist weitaus reicher als die sichtbare Seite. Neben Preis und Adresse erhalten Sie zestimate und rentZestimate — Zillows eigene Verkaufs- und Mietbewertungen — sowie homeStatus (zum Verkauf, verkauft, zur Miete), daysOnZillow, Grundstücks- und Wohnfläche sowie präzise Breiten- und Längengrade. Das ist alles, was ein Vergleichsmodell, eine Lead-Scoring-Pipeline oder ein Marktdashboard benötigt, geliefert als ein sauberes JSON-Objekt pro Immobilie anstelle von einem Dutzend brüchiger CSS-Selektoren, die beim nächsten Redesign brechen.

Die Such-API läuft auf Kartenkoordinaten

Zillows Suche ist nicht keyword-orientiert — sie ist kartenorientiert. Im Hintergrund löst das Absenden einer Suche eine Anfrage an zillow.com/async-create-search-page-state mit einem searchQueryState-Objekt aus, dessen zentrales Feld mapBounds ist: vier Zahlen (Norden, Süden, Osten, Westen), die ein Rechteck auf der Karte zeichnen. Geben Sie ihm einen Begrenzungsrahmen und es gibt jede darin enthaltene Liste als strukturiertes JSON zurück:

def search_area(bounds, page=1):
    url = "https://www.zillow.com/async-create-search-page-state"
    body = {
        "searchQueryState": {
            "pagination": {"currentPage": page},
            "mapBounds": bounds,   # {'north':..,'south':..,'east':..,'west':..}
            "filterState": {"sortSelection": {"value": "days"}},
        },
        "wants": {"cat1": ["listResults", "mapResults"], "cat2": ["total"]},
        "requestId": 2,
    }
    r = requests.put(url, json=body, headers=HEADERS, proxies=proxies, timeout=20)
    return r.json()["cat1"]["searchResults"]["listResults"]

# New Haven, CT bounding box
listings = search_area({"north": 41.366, "south": 41.230,
                        "east": -72.827, "west": -73.030})
Flussdiagramm des Scraping von Zillow im großen Maßstab: Definieren Sie ein Kartenbegrenzungsfeld, rufen Sie die Such-API für JSON auf, holen Sie es über einen Wohnproxy ab und teilen Sie Quadranten, um das Ergebnislimit zu überwinden.
Steuern Sie Zillow mit Kartenkoordinaten: Der Begrenzungsrahmen ist die Abfrage und Wohn-IPs halten PerimeterX ruhig.

Überwinden Sie die 820-Ergebnisgrenze

Zillow paginiert nur 20 Seiten mit etwa 41 Einträgen, sodass eine einzelne Suche bei ungefähr 820 Ergebnissen endet, egal wie viele Häuser in der Gegend sind. Dichte Märkte verbergen Tausende mehr. Der Workaround ist rekursives Quadrantensplitting: Wenn ein Begrenzungsrahmen die maximale Seitenzahl zurückgibt, teilen Sie ihn in vier kleinere Boxen und durchsuchen Sie jede; unterteilen Sie weiter, bis jede Box weniger als das Limit zurückgibt. Diese Zoom-in-Strategie kann Hunderttausende von Einträgen aus einer Metropole aufdecken, die die flache Suche niemals zeigen würde — und sie unterteilt nur dort, wo die Dichte es rechtfertigt, sodass Sie keine Anfragen an leere Landschaften verschwenden.

Diese Gründlichkeit hat ihren Preis: Jede Unterteilung vervielfacht die Anfragen, sodass eine dichte Metropole eine Suche in Dutzende verwandeln kann. Planen Sie dafür — begrenzen Sie die Rekursionstiefe und zoomen Sie nur dort, wo die Ergebnisanzahl es rechtfertigt, was der Algorithmus für Sie tut, indem er nur dann unterteilt, wenn eine Box immer noch die maximale Seitenanzahl erreicht. Für eine nächtliche Aktualisierung einer ganzen Stadt landen die meisten Anfragen dann auf den wenigen dichten Innenstadtboxen, während die Vororte in einem einzigen Durchgang gelöst werden, sodass Sie genau dort in die Tiefe investieren, wo der Bestand ist und nirgendwo sonst.

PerimeterX ist der Grund, warum naive Scraper scheitern

Zillows Blockierung basiert nicht primär auf der Rate; es ist PerimeterX (jetzt HUMAN), das die Anfrage profiliert. Rechenzentrums-IPs, fehlende Browser-Header und unmenschliches Timing lösen einen 403 oder eine Herausforderung aus — das ist es, was ein assert status == 200 wirklich überprüft. Die Lösung ist eine kohärente, vertrauenswürdige Anfrage: US-Wohnproxies, sodass die Exit-IP wie ein Hauskäufer aussieht, realistische Browser-Header und exponentielles Backoff, das zu einer frischen IP wechselt, wenn ein 403 auftritt, anstatt die verbrannte erneut zu versuchen. Unsere Analyse von wie PerimeterX Automatisierung erkennt behandelt die Signale ausführlich; die gleiche Haltung gilt für Walmart, das denselben Anbieter verwendet.

Wenn PerimeterX strenger wird oder Sie lieber keine Browserflotte pflegen möchten, rendert eine Scraper API die Seite, rotiert Wohn-IPs und beseitigt die Herausforderung für Sie, indem sie dasselbe versteckte JSON ohne den betrieblichen Aufwand zurückgibt.

Scrapen Sie Zillow hinter PerimeterX mit Wohn-IPs

Statistikpanel, das Zillows 110 Millionen Immobilien, 245 Millionen monatliche Besucher, 820-Ergebnis-Suchlimit und 600 Tausend Ergebnisse durch Quadrantensplitting zeigt
Der Maßstab ist enorm, aber eine Suche endet bei 820 — das Engineering um diese Grenze herum ist die eigentliche Arbeit.

Wann man stattdessen Kreisaufzeichnungen verwenden sollte

Zillow ist hervorragend für Listings, Fotos und Schätzungen, aber es ist eine sekundäre Quelle. Für autoritative Eigentumsverhältnisse, Verkaufshistorie und bewertete Werte veröffentlichen Kreisassessoren und Recorder-Ämter öffentliche Aufzeichnungen — oft über ihre eigenen Portale oder Massendatenexporte. Wenn Ihr Anwendungsfall Titel, Vergleiche oder Steuerdaten anstelle von Live-Listings ist, sind Kreisaufzeichnungen sauberer, permissiver zu sammeln und völlig frei von PerimeterX. Verwenden Sie Zillow für das Marktsignal und Kreisaufzeichnungen für die Wahrheit vor Ort.

Ist das Scrapen von Zillow legal?

Dies sind allgemeine Informationen, keine Rechtsberatung. Öffentlich verfügbare Listendaten — Preise, Adressen, Immobilienattribute — gelten im Allgemeinen als fair zu sammeln, wenn sie in respektvollen Raten erfolgen. Zillow-Ergebnisse können jedoch persönliche Daten enthalten: Namen von Agenten, Telefonnummern und Maklerdetails. Diese sind unter der DSGVO und ähnlichen Gesetzen geschützt, also vermeiden Sie es, sie ohne rechtliche Grundlage zu sammeln und zu speichern. Sammeln Sie die Immobiliendaten, nicht die Personen.

Häufig gestellte Fragen

Kann ich Zillow-Daten scrapen?

Ja — öffentlich sichtbare Listendaten können gesammelt werden. Zillow bettet jeden Immobiliendatensatz als JSON in einem Script-Tag (__NEXT_DATA__ oder der Apollo-Cache) ein, und seine Suche läuft auf einer Map-Bounds-API, die Sie direkt aufrufen können. Das Hindernis ist nicht der Zugang, sondern PerimeterX, daher benötigen Sie Wohn-IPs und kohärente Header, um 403s zu vermeiden.

Hat Zillow eine API?

Zillow bietet etwa 20 offizielle APIs, darunter Property Details und Neighborhood Data, aber sie erfordern Schlüssel, haben Nutzungslimits und decken nicht jedes Feld oder jeden Massenanwendungsfall ab. Viele Teams scrapen stattdessen die öffentlichen Seiten, gerade weil das versteckte JSON bereits den Preis, die Betten, die Bäder, die Fläche, das Zestimate und die Mietschätzung enthält, die sie benötigen.

Warum erhält mein Zillow-Scraper einen 403?

Ein 403 bei Zillow ist fast immer PerimeterX, nicht ein Ratenlimit. Rechenzentrums-IPs, fehlende oder inkonsistente Browser-Header und robotisches Anforderungs-Timing lösen es aus. Wechseln Sie zu US-Wohnproxies, senden Sie realistische Header, fügen Sie menschliche Abstände hinzu und wechseln Sie bei jedem 403 mit exponentiellem Backoff zu einer frischen IP, anstatt die blockierte zu hämmern.

Wie scrapt man mehr als 820 Zillow-Listings aus einem Gebiet?

Eine einzelne Suche endet bei etwa 820 Ergebnissen (20 Seiten mit 41). Um tiefer zu gehen, teilen Sie das Kartenbegrenzungsfeld in vier Quadranten und durchsuchen Sie jeden; unterteilen Sie rekursiv jeden Quadranten, der immer noch das Limit erreicht. Dieser Zoom-in-Ansatz unterteilt nur dichte Bereiche, sodass er das vollständige Inventar einer Metropole erfasst, ohne Anfragen an spärliche Regionen zu verschwenden.

Überspringen Sie das HTML und lesen Sie das eingebettete JSON, steuern Sie die Suche durch Kartenbegrenzungen, teilen Sie Quadranten, um das Limit zu überwinden, und leiten Sie alles durch saubere Wohn-IPs, um PerimeterX voraus zu sein. Tun Sie das und Zillow wird zu einem strukturierten Immobilien-Feed anstelle einer Wand von 403s.

Holen Sie sich Zillow-JSON, ohne gegen PerimeterX zu kämpfen