Sådan scraper du Zillow med Python (uden at blive blokeret)

Sidst opdateret den April 15, 2026
Sådan scraper du Zillow med Python (uden at blive blokeret)

Zillow ligger oven på 160 millioner amerikanske ejendomsoptegnelser, og at få de data ud i stor skala er en af de mest efterspurgte — og mest frustrerende — opgaver inden for ejendomsdata. Hvis du nogensinde har prøvet at scrape Zillow og endt med at stirre på en CAPTCHA-side i stedet for boligannoncer, er du langt fra alene.

Jeg har brugt meget tid på at undersøge og teste forskellige måder at scrape Zillow på — både med Python og med no-code-værktøjer, som vi har bygget hos Thunderbit. Denne guide dækker begge spor. Uanset om du vil have den fulde Python-gennemgang med anti-bot-strategier, eller du bare har brug for 200 boliger i et regneark inden frokost, er der noget her til dig. Vi ser på, hvorfor Zillow-data er vigtige, hvordan siden er bygget under motorhjelmen, en trinvis Python-tutorial, de præcise grunde til at scrapers fejler, og hvordan du automatiserer gentagne scraping-opgaver til prisovervågning.

Hvorfor overhovedet scrape Zillow-data?

Zillow er den største samling af amerikanske data om boligejendomme. Sitet har 210 millioner besøg om måneden og rummer omkring 750.000+ aktive boligannoncer til salg samt 1,9 millioner lejeboliger. Platformen står for mere end 50% af al trafik til amerikanske ejendomsportaler — mere end dobbelt så meget som den nærmeste konkurrent.

zillow_stats_998c14e590.png

Inden du kaster dig ud i Python-kode, er det vigtigt at vide, at Python ikke er den eneste måde at scrape Zillow på, og at det forkerte valg kan koste dig timer. Python-værktøjer som httpx og BeautifulSoup kræver et mellemniveau, manuel håndtering af headers og proxies, kører i moderat tempo (1–3 sekunder pr. side) og kræver løbende vedligeholdelse, selvom de er gratis; Selenium eller Playwright forbedrer anti-bot-håndtering ved at rendere JavaScript, men er langsommere (5–15 sekunder pr. side) og stadig vedligeholdelsestunge; scraping-API’er som ScraperAPI eller ScrapFly er hurtigere med indbygget anti-bot-support og moderat drift, men koster $30–599 om måneden; Zillows officielle API via Bridge Interactive er hurtig og kræver lidt vedligeholdelse, men er begrænset og koster omkring $500 om måneden; og no-code-værktøjer som Thunderbit er begyndervenlige, hurtige, kræver ingen vedligeholdelse takket være AI-tilpasning og tilbyder typisk en freemium-model.

Tidsbesparelsen alene er markant. Manuel research på tværs af 50+ postnumre kan nemt æde 15–20 timer om ugen. Automatiseret scraping kan gøre det samme på få minutter — en reduktion i tidsforbruget på 99,7%.

Alle måder at scrape Zillow på: Python vs. API vs. no-code (sammenlignet)

Inden du hopper direkte til Python-kode, så husk at "scrape Zillow med Python" ikke er din eneste mulighed. Det forkerte valg kan koste dig timer. Her er en side-by-side sammenligning, så du hurtigt kan vælge selv:

MetodeFærdighedsniveauAnti-bot-håndteringHastighedVedligeholdelsePris
Python + httpx/BeautifulSoupMellemManuel (headers, proxies)Moderat (1–3s/side)Høj (selectors går i stykker)Gratis
Python + Selenium/PlaywrightMellemBedre (renderer JS)Langsom (5–15s/side)HøjGratis
Scraping-API (ScraperAPI, ScrapFly)MellemIndbyggetHurtigMellem$30–599/md.
Zillows officielle API (Bridge Interactive)Begynder–MellemN/AHurtigLav~ $500/md., begrænset adgang
No-code-værktøj (Thunderbit)BegynderIndbygget (AI tilpasser sig)HurtigIngen (AI læser siden igen)Freemium

Hvis du har brug for data med det samme uden at skrive kode, så start med Thunderbit. Hvis du vil forstå teknikken eller har brug for fuld kontrol, så læs videre til Python-gennemgangen.

Den 2-minutters løsning: scrape Zillow med Thunderbit (ingen kode nødvendig)

Før vi dykker ned i Python, får du her en løsning til dig, der bare vil have Zillow-data hurtigt — uden Python-opsætning, uden proxy-konfiguration og uden vedligeholdelse af selectors. Vi byggede denne arbejdsgang i Thunderbit netop for at hente strukturerede ejendomsdata uden teknisk overhead.

Sværhedsgrad: Begynder
Tidsforbrug: ~2 minutter
Det skal du bruge: Chrome-browser, Thunderbit Chrome-udvidelse (gratis niveau virker)

Trin 1: Installer Thunderbit og åbn Zillow

Installer Thunderbit-udvidelsen fra Chrome Web Store. Gå til en Zillow-side med søgeresultater — for eksempel en søgning efter boliger i Houston, TX.

Trin 2: Klik på "AI Suggest Fields"

Åbn Thunderbit-sidepanelet, og klik på "AI Suggest Fields." AI’en læser siden og foreslår automatisk kolonner: pris, adresse, soveværelser, badeværelser, kvadratmeter, Zestimate, annonce-URL og meget mere. I mine tests identificerer den typisk 20+ felter helt uden manuel opsætning.

Trin 3: Klik på "Scrape"

Tryk på Scrape-knappen. Data fyldes ind i en struktureret tabel inde i udvidelsen. Thunderbit håndterer Zillows paginering automatisk — både klikbaseret og uendelig scroll.

Trin 4: Berig med scraping af undersider

Vil du have data fra detaljesider som skattehistorik, skolernes vurderinger eller prisudvikling? Brug "Scrape Subpages" til at berige din tabel. Thunderbit følger hver annonce-URL og henter de ekstra felter — helt uden ekstra kode.

Trin 5: Eksportér

Eksportér til Google Sheets, Excel, Airtable eller Notion. Eksporten er gratis.

Hvorfor Thunderbit fungerer godt til Zillow

Den store fordel her er robusthed. Thunderbits AI læser sidens struktur på ny, hver gang du scraper. Når Zillow ændrer layout (hvilket sker ofte), er der ingen skrøbelige CSS-selectors, der skal repareres. AI’en tilpasser sig automatisk. Det løser reelt den "iboende skrøbelighed" i kodede scrapers, som frustrerer så mange brugere.

Hvilke data kan du scrape fra Zillow? (20+ felter)

De fleste guides tager pris og adresse og stopper der. Zillow-annoncer rummer faktisk langt flere udtrækkelige data, end man skulle tro — her er en referenceoversigt:

FeltHvor det findesSværhedsgrad
UdbudsprisSøgning + detaljeLet
Adresse / postnummerSøgning + detaljeLet
ZestimateSøgning + detaljeLet
Pris-historik (hver hændelse)DetaljeSvær (indlejret JSON)
SkattehistorikDetaljeSvær (indlejret JSON)
Soveværelser / badeværelser / m²Søgning + detaljeLet
ByggeårDetaljeLet
HOA-gebyrDetaljeMellem
Walk Score / Transit ScoreDetalje (iframe)Svær (kræver JS-rendering)
SkolevurderingerDetaljeMellem
GrundstørrelseDetaljeLet
Dage på ZillowSøgningLet
Mægler / ejendomskontorSøgning + detaljeMellem
MLS #DetaljeLet
EjendomstypeSøgning + detaljeLet
Breddegrad / længdegrad__NEXT_DATA__ JSONMellem
BeskrivelsestekstDetaljeLet
Foto-URL’erSøgning + detaljeMellem
Rent ZestimateDetaljeMellem
Sammenlignelige salg i nærhedenDetaljeSvær

De "svære" felter — pris-historik, skattehistorik, sammenlignelige salg — ligger i indlejret JSON på detaljesiderne. Python-afsnittet nedenfor viser præcis, hvordan du udtrækker dem. Og hvis du hellere vil springe koden over, kan Thunderbits AI Suggest Fields automatisk genkende de fleste af disse kolonner, mens Subpage Scraping henter detaljefelterne automatisk.

Sådan sætter du dit Python-miljø op til at scrape Zillow

Sværhedsgrad: Mellem
Tidsforbrug: ~5 minutter til opsætning, ~30 minutter til hele gennemgangen
Det skal du bruge: Python 3.8+, Chrome-browser (til at inspicere sider), en teksteditor eller IDE

Installer de nødvendige biblioteker:

pip install httpx beautifulsoup4 pandas lxml

Her er, hvad hvert bibliotek bruges til:

  • httpx — HTTP-klient med bedre ydeevne end requests og støtte for async
  • beautifulsoup4 + lxml — HTML-parsing
  • pandas — eksport til CSV/Excel
  • Valgfrit: selenium eller playwright, hvis du skal rendere sider med meget JavaScript

Forstå Zillows sidstruktur, før du scraper

zillow_structure_046e848770.png

Det her er det vigtigste at forstå, før du skriver kode. Zillow er en Next.js-applikation — bekræftet af ingeniørindlæg fra Zillow-medarbejdere. Det betyder, at det meste af dataen, du vil have, ikke ligger i de synlige HTML-elementer. Det er indlejret i en <script id="__NEXT_DATA__"> JSON-blok.

Åbn en hvilken som helst Zillow-boligside, tryk F12, gå til Elements, og søg efter __NEXT_DATA__. Du finder et massivt JSON-objekt med alle annonceoplysningerne — priser, koordinater, ejendomsdetaljer, pris-historik, skatteregistre, skolevurderinger og mere.

Hvorfor er det vigtigt? Zillows CSS-klassenavne er hash-baserede (genereret af styled-components) og ændrer sig ved hver deployment. En klasse som StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0 vil have en helt anden hash næste uge. Enhver scraper, der bruger CSS-selectors, vil derfor ofte gå i stykker.

JSON-tilgangen via __NEXT_DATA__ er langt mere stabil, fordi den slet ikke afhænger af HTML-strukturen.

Vigtige JSON-stier for søgeresultater:

StiIndhold
props.pageProps.searchPageState.cat1.searchResults.listResultsArray med søgeresultater
props.pageProps.searchPageState.cat1.searchResults.mapResultsResultater i kortvisning
props.pageProps.searchPageState.cat1.searchList.totalPagesSamlet antal tilgængelige sider

På detaljesider bruger nogle __NEXT_DATA__, mens andre bruger en alternativ script-tag med hdpApolloPreloadedData. Koden nedenfor håndterer begge dele.

Trin for trin: Sådan scraper du Zillow med Python

Trin 1: Sæt HTTP-headers op for at undgå at blive blokeret med det samme

Sender du en ren httpx.get() til Zillow, får du en CAPTCHA-side i stedet for boligdata. Zillow bruger PerimeterX (HUMAN Security) sammen med Cloudflare — begge vurderet til 8/10 i sværhedsgrad af scraping-benchmarks. Systemet tjekker din TLS-fingeraftryk, HTTP-headers og IP-ry.

Her er de minimumsheaders, der virker i 2025:

import httpx

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                   "(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,"
              "image/avif,image/webp,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Ch-Ua": '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
    "Sec-Ch-Ua-Platform": '"Windows"',
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Upgrade-Insecure-Requests": "1",
}

Sec-Ch-Ua-headers er afgørende. Mange tutorials udelader dem — og det er præcis derfor, deres kode ikke virker mod PerimeterX.

Trin 2: Scrape Zillow-søgeresultater

Zillows søge-URL’er følger et ret forudsigeligt mønster. For Houston, TX:

  • Side 1: https://www.zillow.com/houston-tx/
  • Side 2: https://www.zillow.com/houston-tx/2_p/
  • Side 3: https://www.zillow.com/houston-tx/3_p/

Hver side indeholder omkring 41 boliger. Zillow sætter en grænse ved 20 sider (~820 annoncer). For større datasæt skal du opdele geografisk (mere om det senere).

Her er koden til at scrape søgeresultater ved at hente data fra __NEXT_DATA__-JSON’en:

from bs4 import BeautifulSoup
import json
import time
import random

def scrape_zillow_search(url):
    """Scrape listing data from a Zillow search results page."""
    response = httpx.get(url, headers=headers, timeout=15)

    if response.status_code != 200:
        print(f"Got status {response.status_code} for {url}")
        return []

    soup = BeautifulSoup(response.text, "lxml")
    script_tag = soup.find("script", {"id": "__NEXT_DATA__"})

    if not script_tag:
        print("No __NEXT_DATA__ found — likely blocked by CAPTCHA")
        return []

    next_data = json.loads(script_tag.string)

    try:
        results = (
            next_data["props"]["pageProps"]["searchPageState"]
            ["cat1"]["searchResults"]["listResults"]
        )
    except KeyError:
        print("Unexpected JSON structure — Zillow may have changed its format")
        return []

    listings = []
    for item in results:
        listing = {
            "zpid": item.get("zpid"),
            "address": item.get("addressStreet"),
            "city": item.get("addressCity"),
            "state": item.get("addressState"),
            "zipcode": item.get("addressZipcode"),
            "price": item.get("unformattedPrice") or item.get("price"),
            "beds": item.get("beds"),
            "baths": item.get("baths"),
            "sqft": item.get("area"),
            "zestimate": item.get("zestimate"),
            "days_on_zillow": item.get("daysOnZillow"),
            "listing_url": item.get("detailUrl"),
            "img_src": item.get("imgSrc"),
            "property_type": item.get("hdpData", {}).get("homeInfo", {}).get("homeType"),
            "latitude": item.get("latLong", {}).get("latitude"),
            "longitude": item.get("latLong", {}).get("longitude"),
        }
        listings.append(listing)

    return listings

For at scrape flere sider, skal du loop’e med pauser:

all_listings = []
base_url = "https://www.zillow.com/houston-tx/"

for page in range(1, 6):  # Første 5 sider
    url = base_url if page == 1 else f"{base_url}{page}_p/"
    print(f"Scraper side {page}...")

    page_listings = scrape_zillow_search(url)
    all_listings.extend(page_listings)

    # Tilfældig pause mellem 3-7 sekunder
    delay = random.uniform(3, 7)
    time.sleep(delay)

print(f"Samlet antal scrape-de boliger: {len(all_listings)}")

Du bør nu se strukturerede boligdata samle sig i all_listings. Hvis du får tomme resultater, så tjek afsnittet "Hvorfor scrapers går i stykker" nedenfor.

Trin 3: Scrape Zillows detaljesider

Søgeresultater giver dig det basale. Detaljesider indeholder de dybere data: pris-historik, skattehistorik, skolevurderinger, agentinfo og ejendomsbeskrivelser. Hver annonce-URL fra trin 2 peger på en detaljeside.

Zillows detaljesider bruger to mulige dataformater. Her er kode, der håndterer begge:

def scrape_zillow_detail(url):
    """Scrape detailed property data from a Zillow listing page."""
    response = httpx.get(url, headers=headers, timeout=15)

    if response.status_code != 200:
        return None

    soup = BeautifulSoup(response.text, "lxml")

    # Prøv __NEXT_DATA__ først (mest almindeligt)
    script_tag = soup.find("script", {"id": "__NEXT_DATA__"})
    if script_tag:
        next_data = json.loads(script_tag.string)
        try:
            cache_str = next_data["props"]["pageProps"]["componentProps"]["gdpClientCache"]
            cache = json.loads(cache_str)
            first_key = next(iter(cache))
            prop = cache[first_key]["property"]
            return extract_property_fields(prop)
        except (KeyError, StopIteration):
            pass

    # Fallback: hdpApolloPreloadedData
    apollo_tag = soup.find("script", {"id": "hdpApolloPreloadedData"})
    if apollo_tag:
        raw = json.loads(apollo_tag.string)
        api_cache = json.loads(raw["apiCache"])
        for key, value in api_cache.items():
            if "ForSale" in key or "property" in str(value)[:100]:
                prop = value.get("property", value)
                return extract_property_fields(prop)

    return None


def extract_property_fields(prop):
    """Extract structured fields from a Zillow property JSON object."""
    return {
        "zpid": prop.get("zpid"),
        "zestimate": prop.get("zestimate"),
        "rent_zestimate": prop.get("rentZestimate"),
        "description": prop.get("description"),
        "year_built": prop.get("yearBuilt"),
        "lot_size": prop.get("lotSize"),
        "hoa_fee": prop.get("monthlyHoaFee"),
        "mls_id": prop.get("mlsid"),
        "broker_name": prop.get("brokerName") or prop.get("attributionInfo", {}).get("brokerName"),
        "price_history": [
            {
                "date": event.get("date"),
                "event": event.get("event"),
                "price": event.get("price"),
            }
            for event in prop.get("priceHistory", [])
        ],
        "tax_history": [
            {
                "year": record.get("time"),
                "tax_paid": record.get("taxPaid"),
                "value": record.get("value"),
            }
            for record in prop.get("taxHistory", [])
        ],
        "schools": [
            {
                "name": school.get("name"),
                "rating": school.get("rating"),
                "distance": school.get("distance"),
            }
            for school in prop.get("schools", [])
        ],
    }

Loop gennem dine annonce-URLs med pauser:

detail_data = []
for listing in all_listings[:10]:  # Start med 10 for at teste
    detail_url = listing.get("listing_url")
    if not detail_url:
        continue

    if not detail_url.startswith("http"):
        detail_url = f"https://www.zillow.com{detail_url}"

    print(f"Scraper detalje: {detail_url}")
    detail = scrape_zillow_detail(detail_url)

    if detail:
        detail_data.append({**listing, **detail})

    time.sleep(random.uniform(3, 8))

Efter dette trin bør du have en liste af dictionaries med både søge-niveau- og detaljeniveau-data for hver ejendom.

Trin 4: Håndter paginering for at scrape flere sider

For områder med mere end 820 annoncer (20-siders loftet) skal du opdele geografisk. Zillows interne API accepterer mapBounds-parametre. Strategien: del kortet op i kvadranter og scrape hver for sig.

def split_bounds(bounds):
    """Split map bounds into 4 quadrants."""
    mid_lat = (bounds["north"] + bounds["south"]) / 2
    mid_lng = (bounds["east"] + bounds["west"]) / 2

    return [
        {"north": bounds["north"], "south": mid_lat, "east": bounds["east"], "west": mid_lng},
        {"north": bounds["north"], "south": mid_lat, "east": mid_lng, "west": bounds["west"]},
        {"north": mid_lat, "south": bounds["south"], "east": bounds["east"], "west": mid_lng},
        {"north": mid_lat, "south": bounds["south"], "east": mid_lng, "west": bounds["west"]},
    ]

For de fleste behov — overvågning af 50–200 boliger i et bestemt område — er den almindelige URL-paginering tilstrækkelig. Kvadrant-metoden er til by- eller statsdækkende scraping.

Trin 5: Eksportér dine scrape-de Zillow-data

Gem det hele som CSV med pandas:

import pandas as pd

df = pd.DataFrame(detail_data)
df.to_csv("zillow_houston_listings.csv", index=False)
print(f"Eksporterede {len(df)} boliger til zillow_houston_listings.csv")

Til JSON-eksport:

with open("zillow_houston_listings.json", "w") as f:
    json.dump(detail_data, f, indent=2)

Hvis du vil springe eksporttrinnet helt over, eksporterer Thunderbit gratis til Google Sheets, Airtable og Notion — nyttigt, hvis du vil have data i et samarbejdsvenligt format med det samme.

Hvorfor Zillow-scrapers går i stykker (og hvordan du bygger robuste løsninger)

Det her er overlevelsesguiden.

Efter min erfaring går scrapers i stykker på Zillow af tre helt konkrete grunde — og hver har en praktisk løsning.

PerimeterX og CAPTCHA’er: Derfor returnerer dine requests tomme data

Zillows PerimeterX-integration tjekker flere signaler samtidigt: TLS-fingeraftryk, HTTP-headers, IP-ry og anmodningsmønstre. Når den opdager automation, viser den en "Press & Hold"-CAPTCHA-side i stedet for boligdata.

Det præcise fejlscenarie: Du sender en request med standard Python-headers. HTML-svaret indeholder PerimeterX challenge-scripts i stedet for ejendomsdata — og dit BeautifulSoup-parse finder ingen __NEXT_DATA__-tag.

Løsningen: Brug de fulde browser-lignende headers fra trin 1. Hvis du laver mere end et par dusin requests, har du også brug for proxy-rotation (beskrevet nedenfor). Til tung scraping bør du overveje et bibliotek som curl_cffi med impersonate="chrome" — det er den eneste Python HTTP-klient, der kan matche et rigtigt Chrome-TLS-fingeraftryk.

Dynamiske CSS-selectors: Derfor returnerer BeautifulSoup None

Hvis du bruger CSS-selectors som .list-card-price eller klassenavne med hashes, vil din scraper gå i stykker hver gang Zillow ruller ny kode ud.

Zillow bruger styled-components, som genererer klassenavne som StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0. Hash-delen ændrer sig for hver build.

Løsningen: Brug slet ikke CSS-selectors. Hent data fra __NEXT_DATA__-JSON-blokken som vist i koden ovenfor. Den metode har været stabil i årevis, fordi JSON-strukturen ændrer sig langt sjældnere end HTML-markup.

Hvis du absolut skal bruge HTML-parsing, så kig efter data-test-attributter (fx data-test="property-card") eller brug delvise class-matches som [class*="PropertyCard"]. Men JSON-udtræk er den mere pålidelige vej.

Proxy-rotation og eksponentiel backoff: Kode der overlever IP-bans

Datacenter-IP’er bliver med det samme blacklisted af Zillow. Du har brug for residential proxies for stabil adgang. Sikker hastighed: 1 request hver 3–8 sekunder pr. IP, og hold dig under ca. 500 requests i timen.

Her er en retry-decorator med eksponentiel backoff og tilfældig jitter:

import random
import time

def backoff_with_jitter(attempt, base_delay=2, max_delay=60):
    """AWS-style full jitter exponential backoff."""
    delay = min(max_delay, base_delay * (2 ** attempt))
    return random.uniform(0, delay)

def fetch_with_retry(url, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = httpx.get(url, headers=headers, timeout=15)
            if response.status_code == 200:
                return response
            if response.status_code in (403, 429):
                delay = backoff_with_jitter(attempt, base_delay=5)
                print(f"Blokeret ({response.status_code}). Prøver igen om {delay:.1f}s...")
                time.sleep(delay)
                continue
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            time.sleep(backoff_with_jitter(attempt))
    return None

Og en simpel proxy-rotationspool:

class ProxyPool:
    def __init__(self, proxies):
        self.proxies = proxies
        self.index = 0
        self.failures = {}

    def get_next(self):
        proxy = self.proxies[self.index % len(self.proxies)]
        self.index += 1
        return {"http://": proxy, "https://": proxy}

    def report_failure(self, proxy):
        self.failures[proxy] = self.failures.get(proxy, 0) + 1
        if self.failures[proxy] > 3:
            self.proxies.remove(proxy)

# Brug:
pool = ProxyPool(proxies=[
    "http://user:pass@residential1.example.com:8080",
    "http://user:pass@residential2.example.com:8080",
])

Hos proxy-udbydere tilbyder DataImpulse residential proxies til omkring $1/GB (den billigste løsning), mens IPRoyal og Smartproxy er solide mellemklassevalg til $4–7/GB.

Det vedligeholdelsesfri alternativ

Hvis du scraper Zillow regelmæssigt og er træt af at rette ødelagte selectors eller styre proxy-pools, læser Thunderbits AI sidens struktur helt forfra ved hver scraping. Ingen selectors at vedligeholde, ingen proxy-konfiguration. Det løser reelt den skrøbelighed, som gør kodede scrapers til en tilbagevendende hovedpine.

Automatisér Zillow-scraping: Planlægning og prisovervågning

Alle ejendomsinvestorer, jeg har talt med, vil have dette, og ingen andre Zillow-guides dækker det: gentagne automatiske scraping-kørsler til prisovervågning.

For Python-brugere: Cron-jobs og registrering af prisændringer

Sæt et cron-job op, der kører din scraper hver uge og markerer prisændringer:

import pandas as pd
from datetime import datetime

def detect_price_changes(new_data, historical_file, threshold=0.05):
    """Compare new scrape with historical data, flag changes > threshold."""
    try:
        old = pd.read_csv(historical_file)
    except FileNotFoundError:
        new_data.to_csv(historical_file, index=False)
        print("Første kørsel — baseline-data gemt.")
        return pd.DataFrame()

    merged = new_data.merge(old, on="zpid", suffixes=("_new", "_old"))
    merged["price_change_pct"] = (
        (merged["price_new"] - merged["price_old"]) / merged["price_old"]
    )
    alerts = merged[merged["price_change_pct"].abs() > threshold]

    # Tilføj nye data med tidsstempel
    new_data["scraped_at"] = datetime.now().isoformat()
    new_data.to_csv(historical_file, mode="a", header=False, index=False)

    return alerts

Tilføj dette til din crontab for ugentlige kørsler om mandagen kl. 6:

0 6 * * 1 cd /path/to/scraper && python zillow_monitor.py

Et praktisk eksempel: overvåg 50 Austin, TX-annoncer hver uge. Hver mandag scraper scriptet de aktuelle priser, sammenligner dem med ugen før og outputter en CSV, der fremhæver alle prisfald på over 5%.

For ikke-kodere: Thunderbits Scheduled Scraper

Thunderbits Scheduled Scraper lader dig beskrive intervallet i almindeligt sprog ("hver mandag kl. 9"), indsætte dine Zillow-søge-URL’er og klikke på Schedule. Data eksporteres automatisk til Google Sheets ved hver kørsel. Ingen Python, ingen cron, ingen server at vedligeholde. Det er især nyttigt for ejendomsmæglere eller driftsteams, der har brug for stabil prisovervågning uden udviklerstøtte.

Tips til ansvarlig scraping af Zillow

Et par noter om at holde sig på den rigtige side af grænsen:

  • Scrape kun offentligt tilgængelige data. Gå ikke ind på sider bag login eller autentificering.
  • Brug fornuftige request-hastigheder. 3–8 sekunder mellem requests. Lad være med at overbelaste serveren.
  • Scrape ikke personlige/private brugerdata. Agentnavne og mægleroplysninger på annoncer er offentlige; brugerkontodata er ikke.
  • Gem og brug data etisk. Markedsresearch, investeringsanalyse og leadgenerering er legitime formål. Spam er ikke.
  • Juridisk kontekst: hiQ v. LinkedIn-afgørelsen slog fast, at scraping af offentligt tilgængelige data ikke bryder CFAA. Meta v. Bright Data (2024) bekræftede lignende principper. Når det er sagt, begrænser Zillows ToS automatisk adgang, og de håndhæver det via IP-bans og CAPTCHA’er frem for retssager. Tjek altid den aktuelle vejledning, og respekter robots.txt.

Vælg den rigtige metode til at scrape Zillow med Python

Den bedste vej afhænger af din situation:

Har du brug for data hurtigt, uden kode? Thunderbit fører dig fra en Zillow-søgeside til et struktureret regneark på cirka 2 minutter. AI’en tilpasser sig layoutændringer, håndterer paginering og eksporterer gratis. Installer Chrome-udvidelsen og prøv den på en Zillow-søgeside.

Vil du have fuld kontrol? Brug Python-koden i denne guide. Hent fra __NEXT_DATA__-JSON (ikke CSS-selectors) for stabilitet. Sæt korrekte browser-lignende headers op. Brug residential proxies og eksponentiel backoff for pålidelighed.

Skal du skalere op? Scraping-API’er som ScrapFly (99% succesrate på Zillow) eller ScraperAPI håndterer proxy- og CAPTCHA-infrastrukturen for dig til $30–599/måned afhængigt af volumen.

Vil du følge priser over tid? Sæt et cron-job op med scriptet til registrering af prisændringer, eller brug Thunderbits Scheduled Scraper for en løsning uden vedligeholdelse.

Dataen er der. Det eneste spørgsmål er, hvor meget ingeniørtid du vil bruge på at få den ud. Hvis du vil have mere om at få webdata ind i regneark, så tjek vores guide til at scrape data fra websites til Excel eller vores opsamling af Zillow-statistikker for den nyeste platformdata. Du kan også se tutorials på Thunderbit YouTube-kanalen.

Prøv Thunderbit til Zillow-scraping Get Started Free

Ofte stillede spørgsmål

Kan man scrape Zillow med Python gratis?

Ja — httpx, BeautifulSoup og pandas er alle gratis og open source. Ulempen er tiden: du skal selv håndtere headers, proxy-rotation og vedligeholdelse af selectors. Forvent at bruge 4–8 timer på den første opsætning og 4–10 timer om måneden på vedligeholdelse, når Zillow ændrer sit site. Thunderbit har også et gratis niveau, hvis du vil slippe helt for kodningsarbejdet.

Har Zillow en officiel API?

Zillow afviklede sin gratis offentlige API i september 2021. Adgang går nu gennem Bridge Interactive, som kræver godkendelse, koster cirka $500/måned og er målrettet licenserede ejendomsprofessionelle. For de fleste brugere — investorer, forskere og mæglere, der laver markedsanalyse — er scraping det praktiske alternativ. Zillow udgiver stadig gratis researchdata som CSV-filer på zillow.com/research/data/, herunder Zillow Home Value Index og Zillow Observed Rent Index.

Hvordan undgår jeg at blive blokeret, når jeg scraper Zillow?

Tre ting: (1) brug realistiske browser-headers, inklusive Sec-Ch-Ua — det er den header, de fleste tutorials overser, og den PerimeterX tjekker først; (2) brug rotation af residential proxies — datacenter-IP’er bliver straks blacklisted; (3) hent data fra __NEXT_DATA__-JSON i stedet for HTML-selectors, så du undgår brud ved layoutændringer. Hold request-hastigheden på 1 hver 3–8 sekunder pr. IP. Eller brug et værktøj som Thunderbit, der håndterer anti-bot-beskyttelse automatisk.

Hvad er den bedste måde at scrape Zillow uden at kode?

Thunderbits AI Web Scraper er den hurtigste vej. Installer Chrome-udvidelsen, gå til en Zillow-søgeside, klik på "AI Suggest Fields" for automatisk at finde kolonnerne, og klik derefter på "Scrape." Eksportér til Google Sheets, Excel, Airtable eller Notion uden at skrive kode. AI’en læser siden helt forfra hver gang, så den går ikke i stykker, når Zillow opdaterer layoutet.

Hvor ofte ændrer Zillow sin struktur på sitet, og hvordan påvirker det scrapers?

Zillow udruller opdateringer ofte — nogle gange ugentligt. Fordi de bruger styled-components, ændrer CSS-klassenavne sig ved hver deployment, og scrapers, der bygger på CSS-selectors, går derfor ofte i stykker. Den mest robuste tilgang i Python er at hente data fra __NEXT_DATA__-JSON-blokken, som ændrer struktur langt sjældnere. Hvis du vil have en løsning uden vedligeholdelse, genlæser Thunderbits AI sidens struktur ved hver scraping og tilpasser sig automatisk til layoutændringer.

Læs mere

Shuai Guan
Shuai Guan
CEO hos Thunderbit | Ekspert i AI-drevet dataautomatisering Shuai Guan er CEO hos Thunderbit og uddannet ingeniør fra University of Michigan. Med næsten ti års erfaring inden for tech og SaaS-arkitektur har han specialiseret sig i at omsætte komplekse AI-modeller til praktiske, no-code værktøjer til dataudtræk. På denne blog deler han ærlige, gennemprøvede indsigter om webscraping og automatiseringsstrategier, så du kan bygge smartere, datadrevne arbejdsgange. Når han ikke optimerer dataflows, bruger han det samme skarpe blik for detaljer i sin passion for fotografi.
Indholdsfortegnelse

Hent en webside bare ved at spørge

Sig, hvad du har brug for, på helt almindeligt engelsk. Eller endnu bedre: sig ingenting.

Prøv Thunderbit gratis
Udtræk data med AI
Overfør nemt data til Google Sheets, Airtable eller Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week