Näin poimit Zillow-tietoja Pythonilla ilman estetyksi tulemista

Viimeksi päivitetty April 15, 2026
Näin poimit Zillow-tietoja Pythonilla ilman estetyksi tulemista

Zillow nojaa yli 160 miljoonan yhdysvaltalaisen kiinteistötietueen varaan, ja näin valtavan datamäärän ulos saaminen on yksi kiinteistödatan työnkulun kysytyimmistä — ja turhauttavimmista — tehtävistä. Jos olet joskus yrittänyt poimia Zillow-dataa ja päätynyt listatietojen sijaan tuijottamaan CAPTCHA-sivua, et todellakaan ole ainoa.

Olen käyttänyt paljon aikaa eri Zillow-scraping-tapojen tutkimiseen ja testaamiseen — sekä Pythonilla että Thunderbitillä rakentamiemme no-code-työkalujen avulla. Tämä opas käy läpi molemmat lähestymistavat. Haluatpa sitten täydellisen Python-opastuksen ja anti-bot-strategiat tai tarvitset vain 200 kohdetta taulukkoon ennen lounasta, tästä löydät sopivan osion. Käymme läpi, miksi Zillow-data on tärkeää, miten sivusto toimii kulissien takana, vaiheittaisen Python-opastuksen, yleisimmät syyt, miksi scraperit kaatuvat, sekä sen, miten toistuvat ajastetut haut voi automatisoida hintaseurantaa varten.

Miksi Zillow-dataa kannattaa ylipäätään hakea?

Zillow on Yhdysvaltojen suurin asuntokiinteistödatan tietovarasto. Sivusto kerää 210 miljoonaa käyntiä kuukaudessa ja sisältää noin 750 000+ aktiivista myyntikohdetta sekä 1,9 miljoonaa vuokrakohdetta. Alusta kattaa yli 50 % kaikesta Yhdysvaltojen kiinteistöportaali-liikenteestä — yli kaksinkertaisesti seuraavaan kilpailijaan verrattuna.

zillow_stats_998c14e590.png

Ennen kuin sukellat Python-koodiin, on hyvä tietää, että Zillow-datan poimiminen Pythonilla ei ole ainoa vaihtoehto, ja väärän menetelmän valinta voi viedä tunteja hukkaan. Python-työkalut, kuten httpx ja BeautifulSoup, vaativat keskitason osaamista, otsikoiden ja proxien manuaalista hallintaa, toimivat kohtalaisella nopeudella (1–3 sekuntia sivua kohden) ja vaativat säännöllistä ylläpitoa, vaikka ne ovat ilmaisia; Selenium tai Playwright parantavat anti-bot-käsittelyä renderöimällä JavaScriptiä, mutta ovat hitaampia (5–15 sekuntia sivua kohden) ja silti ylläpitoraskaita; scraping-API:t kuten ScraperAPI tai ScrapFly ovat nopeampia ja niissä on valmiiksi sisäänrakennettu anti-bot-tuki sekä kohtalainen ylläpitotarve, mutta ne maksavat 30–599 dollaria kuukaudessa; Zillow’n virallinen API Bridge Interactiven kautta on nopea ja vähän ylläpitoa vaativa, mutta rajoitettu ja maksaa noin 500 dollaria kuukaudessa; ja no-code-työkalut kuten Thunderbit ovat aloittelijaystävällisiä, nopeita, eivät vaadi ylläpitoa AI:n mukautuvuuden ansiosta ja tarjoavat yleensä freemium-mallin.

Pelkkä ajansäästö on jo valtava. Manuaalinen tutkimus yli 50 postinumeroalueella voi viedä 15–20 tuntia viikossa. Automatisoitu haku hoitaa saman työn minuuteissa — ajankäyttö pienenee 99,7 %.

Kaikki tavat hakea Zillow-dataa: Python vs. API vs. no-code (vertailu)

Ennen Python-koodiin hyppäämistä on hyvä muistaa, että "scrape Zillow with Python" ei ole ainoa tapa. Väärän menetelmän valitseminen vie aikaa hukkaan. Tässä rinnakkainen vertailu, jonka avulla voit valita itsellesi sopivan tavan:

MenetelmäTaitotasoAnti-bot-käsittelyNopeusYlläpitoKustannus
Python + httpx/BeautifulSoupKeskitasoManuaalinen (otsikot, proxyt)Kohtalainen (1–3 s/sivu)Korkea (valitsimet rikkoutuvat)Ilmainen
Python + Selenium/PlaywrightKeskitasoParempi (renderöi JS:n)Hidas (5–15 s/sivu)KorkeaIlmainen
Scraping API (ScraperAPI, ScrapFly)KeskitasoSisäänrakennettuNopeaKeskitaso30–599 $/kk
Zillow’n virallinen API (Bridge Interactive)Aloittelija–keskitasoEi sovelluNopeaMatala~500 $/kk, rajoitettu pääsy
No-code-työkalu (Thunderbit)AloittelijaSisäänrakennettu (AI mukautuu)NopeaEi mitään (AI lukee sivun uudelleen)Freemium

Jos tarvitset dataa heti ilman koodin kirjoittamista, aloita Thunderbitillä. Jos haluat ymmärtää koko prosessin tai tarvitset täyden muokattavuuden, jatka Python-oppaaseen.

2 minuutin tapa: poimi Zillow-data Thunderbitillä ilman koodausta

Ennen syväsukellusta Pythoniin tässä on reitti sinulle, joka tarvitset Zillow-dataa nopeasti — ilman Pythonin asentamista, proxyjen säätämistä tai valitsimien ylläpitoa. Rakensimme tämän työnkulun Thunderbitillä juuri rakenteisen kiinteistödatan poimimiseen ilman teknistä ylimääräistä vaivaa.

Vaikeustaso: Aloittelija
Aika: noin 2 minuuttia
Tarvitset: Chrome-selaimen, Thunderbit Chrome -laajennuksen (ilmainen taso riittää)

Vaihe 1: Asenna Thunderbit ja avaa Zillow

Asenna Thunderbit-laajennus Chrome Web Storesta. Avaa Zillow’n hakutulossivu — esimerkiksi tee haku kodeista Houstonissa, TX:ssä.

Vaihe 2: Napsauta "AI Suggest Fields"

Avaa Thunderbitin sivupalkki ja napsauta "AI Suggest Fields." AI lukee sivun ja ehdottaa automaattisesti sarakkeita: hinta, osoite, makuuhuoneet, kylpyhuoneet, neliöt, Zestimate, listaus-URL ja paljon muuta. Testeissäni se tunnistaa yleensä yli 20 kenttää ilman manuaalista asetusten tekemistä.

Vaihe 3: Napsauta "Scrape"

Paina Scrape-painiketta. Data täyttyy jäsenneltyyn taulukkoon laajennuksen sisällä. Thunderbit käsittelee Zillow’n sivutuksen automaattisesti — sekä klikkauspohjaisen että jatkuvan vierityksen.

Vaihe 4: Rikasta dataa alisivujen haulla

Haluatko yksityiskohtaisia tietoja, kuten verohistoriaa, kouluarvioita tai hintahistoriaa? Käytä "Scrape Subpages" -toimintoa taulukon rikastamiseen. Thunderbit käy jokaisen kohteen URL-osoitteen läpi ja poimii lisäkentät — ilman ylimääräistä koodia.

Vaihe 5: Vie data

Vie tiedot Google Sheetsiin, Exceliin, Airtableen tai Notioniin. Vienti on ilmainen.

Miksi Thunderbit toimii hyvin Zillow’n kanssa

Todellinen etu on kestävyys. Thunderbitin AI lukee sivun rakenteen tuoreeltaan joka kerta, kun haet dataa. Kun Zillow muuttaa asetteluaan (mikä tapahtuu usein), rikkoutuneita CSS-valitsimia ei tarvitse korjata. AI mukautuu automaattisesti. Tämä ratkaisee aidosti koodattujen scrapers-ratkaisujen "herkästi hajoavan" luonteen, joka turhauttaa niin monia käyttäjiä.

Mitä dataa Zillow’sta voi poimia? (yli 20 kenttää)

Useimmat oppaat hakevat vain hinnan ja osoitteen ja pysähtyvät siihen. Zillow-listaukset sisältävät itse asiassa paljon enemmän poimittavaa dataa kuin moni arvaa — tässä hyödyllinen viitetaulukko:

KenttäMistä se löytyyPoiminnan vaikeus
ListahintaHaku + kohdesivuHelppo
Osoite / postinumeroHaku + kohdesivuHelppo
ZestimateHaku + kohdesivuHelppo
Hintahistoria (jokainen tapahtuma)KohdesivuVaikea (sisäkkäinen JSON)
VerohistoriaKohdesivuVaikea (sisäkkäinen JSON)
Makuuhuoneet / kylpyhuoneet / neliötHaku + kohdesivuHelppo
RakennusvuosiKohdesivuHelppo
TaloyhtiövastikeKohdesivuKeskitaso
Kävely- / joukkoliikennelukuKohdesivu (iframe)Vaikea (vaatii JS-renderöinnin)
KouluarviotKohdesivuKeskitaso
Tontin kokoKohdesivuHelppo
Päiviä Zillow’ssaHakuHelppo
Välittäjä / toimistoHaku + kohdesivuKeskitaso
MLS-numeroKohdesivuHelppo
KiinteistötyyppiHaku + kohdesivuHelppo
Leveys- ja pituusaste__NEXT_DATA__ JSONKeskitaso
KuvaustekstiKohdesivuHelppo
Kuvien URL-osoitteetHaku + kohdesivuKeskitaso
Rent ZestimateKohdesivuKeskitaso
Lähialueen vertailukaupatKohdesivuVaikea

"Vaikeat" kentät — kuten hintahistoria, verohistoria ja vertailukaupat — sijaitsevat sisäkkäisessä JSONissa kohdesivuilla. Alla oleva Python-osio näyttää tarkalleen, miten ne poimitaan. Ja jos haluat mieluummin ohittaa koodin, Thunderbitin AI Suggest Fields tunnistaa automaattisesti useimmat näistä sarakkeista, ja Subpage Scraping hakee kohdesivujen kentät puolestasi.

Python-ympäristön valmistelu Zillow’n hakemiseen

Vaikeustaso: Keskitaso
Aika: noin 5 minuuttia asennukseen, noin 30 minuuttia koko opastukseen
Tarvitset: Python 3.8+, Chrome-selaimen (sivujen tarkastelua varten), tekstieditorin tai IDE:n

Asenna tarvittavat kirjastot:

pip install httpx beautifulsoup4 pandas lxml

Näin kukin niistä toimii:

  • httpx — HTTP-asiakas, joka on nopeampi kuin requests ja tukee asynkronisuutta
  • beautifulsoup4 + lxml — HTML:n jäsentämiseen
  • pandas — datan vientiin CSV/Excel-muotoon
  • Valinnaisesti: selenium tai playwright, jos sinun täytyy renderöidä JavaScript-raskaita sivuja

Ymmärrä Zillow’n sivurakenne ennen kuin alat hakea dataa

zillow_structure_046e848770.png

Tämä on tärkein asia ymmärtää ennen kuin kirjoitat yhtään koodia. Zillow on Next.js-sovellus — tämän vahvistavat Zillow’n työntekijöiden engineering-postaukset. Se tarkoittaa, että suurin osa tarvitsemastasi datasta ei ole näkyvissä HTML-elementeissä. Se on upotettu <script id="__NEXT_DATA__">-JSON-lohkoon.

Avaa mikä tahansa Zillow’n kohdesivu, paina F12, siirry Elements-välilehdelle ja etsi __NEXT_DATA__. Löydät valtavan JSON-objektin, joka sisältää kaiken listausdatan — hinnat, koordinaatit, kohdetiedot, hintahistorian, verotiedot, kouluarviot ja paljon muuta.

Miksi tällä on väliä? Zillow’n CSS-luokat hashataan (styled-componentsin generoimina) ja ne muuttuvat jokaisessa julkaisussa. Luokka kuten StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0 saa ensi viikolla täysin erilaisen hashin. Mikä tahansa CSS-valitsimiin perustuva scraper rikkoutuu säännöllisesti.

__NEXT_DATA__-JSON-lähestymistapa on paljon vakaampi, koska se ei riipu HTML-rakenteesta lainkaan.

Keskeiset JSON-polut hakutuloksille:

PolkuSisältö
props.pageProps.searchPageState.cat1.searchResults.listResultsTaulukko hakutuloksista
props.pageProps.searchPageState.cat1.searchResults.mapResultsKarttanäkymän tulokset
props.pageProps.searchPageState.cat1.searchList.totalPagesSaatavilla olevien sivujen määrä

Kohdesivuilla osa käyttää __NEXT_DATA__-rakennetta ja osa vaihtoehtoista hdpApolloPreloadedData-script-tunnistetta. Alla oleva koodi käsittelee molemmat.

Vaihe vaiheelta: näin poimit Zillow-dataa Pythonilla

Vaihe 1: Aseta HTTP-otsikot, jotta vältyt heti estetyksi tulemiselta

Pelkkä httpx.get()-kutsu Zillow’lle palauttaa listausdatan sijaan CAPTCHA-sivun. Zillow käyttää PerimeterX:ää (HUMAN Security) yhdessä Cloudflaren kanssa — molemmat on arvioitu 8/10 vaikeustasolle scraping-benchmarkeissa. Järjestelmä tarkistaa TLS-jäljen, HTTP-otsikot ja IP:n maineen.

Tässä ovat vähimmäisotsikot, jotka toimivat vuonna 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-otsikot ovat kriittisiä. Monet ohjeet jättävät ne pois — juuri siksi niiden koodi ei toimi PerimeterX:ää vastaan.

Vaihe 2: Hae Zillow’n hakutulokset

Zillow’n hakupolut noudattavat ennustettavaa rakennetta. Houstonissa, TX:ssä:

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

Jokaisella sivulla on noin 41 kohdetta. Zillow rajoittaa tulokset 20 sivuun (~820 kohdetta). Suurempiin aineistoihin sinun täytyy jakaa haku maantieteellisesti (siitä lisää myöhemmin).

Tässä koodi hakutulosten poimimiseen __NEXT_DATA__-JSONista:

from bs4 import BeautifulSoup
import json
import time
import random

def scrape_zillow_search(url):
    """Poimi listausdata Zillow’n hakutulossivulta."""
    response = httpx.get(url, headers=headers, timeout=15)

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

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

    if not script_tag:
        print("__NEXT_DATA__-lohkoa ei löytynyt — todennäköisesti CAPTCHA-eston takia")
        return []

    next_data = json.loads(script_tag.string)

    try:
        results = (
            next_data["props"]["pageProps"]["searchPageState"]
            ["cat1"]["searchResults"]["listResults"]
        )
    except KeyError:
        print("Odottamaton JSON-rakenne — Zillow on ehkä muuttanut formaattia")
        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

Jos haluat hakea useita sivuja, kierrä ne läpi viiveillä:

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

for page in range(1, 6):  # Ensimmäiset 5 sivua
    url = base_url if page == 1 else f"{base_url}{page}_p/"
    print(f"Haetaan sivua {page}...")

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

    # Satunnainen viive 3–7 sekuntia
    delay = random.uniform(3, 7)
    time.sleep(delay)

print(f"Poimittuja kohteita yhteensä: {len(all_listings)}")

Sinun pitäisi nähdä jäsenneltyä listausdataa kertymässä all_listings-muuttujaan. Jos tulos on tyhjä, tarkista alla oleva osio "Miksi scraperit rikkoutuvat".

Vaihe 3: Hae Zillow’n kohdesivujen yksityiskohtaiset tiedot

Hakutulokset antavat perusasiat. Kohdesivut sisältävät syvemmät tiedot: hintahistorian, verohistorian, kouluarviot, välittäjätiedot ja kohteen kuvauksen. Jokainen vaiheessa 2 löytyvä URL vie kohdesivulle.

Zillow’n kohdesivuilla on kaksi mahdollista dataformaattia. Tässä koodi, joka käsittelee molemmat:

def scrape_zillow_detail(url):
    """Poimi yksityiskohtaiset kohdetiedot Zillow’n listaus-sivulta."""
    response = httpx.get(url, headers=headers, timeout=15)

    if response.status_code != 200:
        return None

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

    # Kokeile ensin __NEXT_DATA__-rakennetta (yleisin)
    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

    # Vararatkaisu: 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):
    """Poimi jäsennellyt kentät Zillow’n kohde-JSONista."""
    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"),
               Zillow nojaa yli [160 miljoonan yhdysvaltalaisen kiinteistötietueen](https://thunderbit.com/blog/zillow-statistics) varaan, ja näin valtavan datamäärän ulos saaminen on yksi kiinteistödatan työnkulun kysytyimmistä — ja turhauttavimmista — tehtävistä. Jos olet joskus yrittänyt hakea Zillow-dataa ja päätynyt tuijottamaan CAPTCHA-sivua listatietojen sijaan, et ole ainoa.

Olen käyttänyt paljon aikaa eri Zillow-scraping-tapojen tutkimiseen ja testaamiseen — sekä Pythonilla että Thunderbitillä rakentamiemme no-code-työkalujen avulla. Tämä opas käy läpi molemmat lähestymistavat. Haluatpa sitten kattavan Python-opastuksen ja anti-bot-strategiat tai tarvitset vain 200 kohdetta taulukkoon ennen lounasta, täältä löytyy sopiva osio. Käymme läpi, miksi Zillow-data on tärkeää, miten sivusto toimii taustalla, vaiheittaisen Python-opastuksen, yleisimmät syyt, miksi scraperit kaatuvat, sekä sen, miten toistuvat ajastetut haut voi automatisoida hintaseurantaa varten.

## Miksi Zillow-dataa kannattaa ylipäätään hakea?

Zillow on Yhdysvaltojen suurin asuntokiinteistödatan tietovarasto. Sivusto kerää [210 miljoonaa käyntiä kuukaudessa](https://www.similarweb.com/website/zillow.com/) ja sisältää noin 750 000+ aktiivista myyntikohdetta sekä 1,9 miljoonaa vuokrakohdetta. Alusta kattaa yli 50 % kaikesta Yhdysvaltojen kiinteistöportaali-liikenteestä — yli kaksinkertaisesti seuraavaan kilpailijaan verrattuna.

![zillow_stats_998c14e590.png](https://strapi.thunderbit.com/uploads/zillow_stats_998c14e590.png)

Ennen kuin sukellat Python-koodiin, on hyvä tietää, että Zillow-datan poimiminen Pythonilla ei ole ainoa vaihtoehto, ja väärän menetelmän valinta voi viedä tunteja hukkaan. Python-työkalut, kuten httpx ja BeautifulSoup, vaativat keskitason osaamista, otsikoiden ja proxien manuaalista hallintaa, toimivat kohtalaisella nopeudella (1–3 sekuntia sivua kohden) ja vaativat säännöllistä ylläpitoa, vaikka ne ovat ilmaisia; Selenium tai Playwright parantavat anti-bot-käsittelyä renderöimällä JavaScriptiä, mutta ovat hitaampia (5–15 sekuntia sivua kohden) ja silti ylläpitoraskaita; scraping-API:t kuten ScraperAPI tai ScrapFly ovat nopeampia ja niissä on valmiiksi sisäänrakennettu anti-bot-tuki sekä kohtalainen ylläpitotarve, mutta ne maksavat 30–599 dollaria kuukaudessa; Zillow’n virallinen API Bridge Interactiven kautta on nopea ja vähän ylläpitoa vaativa, mutta rajoitettu ja maksaa noin 500 dollaria kuukaudessa; ja no-code-työkalut kuten Thunderbit ovat aloittelijaystävällisiä, nopeita, eivät vaadi ylläpitoa AI:n mukautuvuuden ansiosta ja tarjoavat yleensä freemium-mallin.

Pelkkä ajansäästö on jo valtava. Manuaalinen tutkimus yli 50 postinumeroalueella voi viedä 15–20 tuntia viikossa. Automatisoitu haku hoitaa saman työn minuuteissa — ajankäyttö pienenee 99,7 %.

## Kaikki tavat hakea Zillow-dataa: Python vs. API vs. no-code (vertailu)

Ennen kuin hyppäät Python-koodiin, on hyvä muistaa, että "scrape Zillow with Python" ei ole ainoa tapa. Väärän menetelmän valitseminen vie aikaa hukkaan. Tässä rinnakkainen vertailu, jonka avulla voit valita itsellesi sopivan tavan:

<Table content={`| **Menetelmä** | **Taitotaso** | **Anti-bot-käsittely** | **Nopeus** | **Ylläpito** | **Kustannus** |
|---|---|---|---|---|---|
| Python + httpx/BeautifulSoup | Keskitaso | Manuaalinen (otsikot, proxyt) | Kohtalainen (1–3 s/sivu) | Korkea (valitsimet rikkoutuvat) | Ilmainen |
| Python + Selenium/Playwright | Keskitaso | Parempi (renderöi JS:n) | Hidas (5–15 s/sivu) | Korkea | Ilmainen |
| Scraping API (ScraperAPI, ScrapFly) | Keskitaso | Sisäänrakennettu | Nopea | Keskitaso | 30–599 $/kk |
| Zillow’n virallinen API (Bridge Interactive) | Aloittelija–keskitaso | Ei sovellu | Nopea | Matala | ~500 $/kk, rajoitettu pääsy |
| No-code-työkalu ([Thunderbit](https://thunderbit.com/)) | Aloittelija | Sisäänrakennettu (AI mukautuu) | Nopea | Ei mitään (AI lukee sivun uudelleen) | Freemium |`} />

Jos tarvitset dataa heti ilman koodin kirjoittamista, aloita Thunderbitillä. Jos haluat ymmärtää koko prosessin tai tarvitset täyden muokattavuuden, jatka Python-oppaaseen.

## 2 minuutin tapa: poimi Zillow-data Thunderbitillä ilman koodausta

Ennen syväsukellusta Pythoniin tässä on reitti sinulle, joka tarvitset Zillow-dataa nopeasti — ilman Pythonin asentamista, proxyjen säätämistä tai valitsimien ylläpitoa. Rakensimme tämän työnkulun Thunderbitillä juuri rakenteisen kiinteistödatan poimimiseen ilman teknistä ylimääräistä vaivaa.

**Vaikeustaso:** Aloittelija  
**Aika:** noin 2 minuuttia  
**Tarvitset:** Chrome-selaimen, [Thunderbit Chrome -laajennuksen](https://chromewebstore.google.com/detail/thunderbit-ai-web-scraper/hbkblmodhbmcakopmmfbaopfckopccgp) (ilmainen taso riittää)

### Vaihe 1: Asenna Thunderbit ja avaa Zillow

Asenna Thunderbit-laajennus Chrome Web Storesta. Avaa Zillow’n hakutulossivu — esimerkiksi tee haku kodeista Houstonissa, TX:ssä.

### Vaihe 2: Napsauta "AI Suggest Fields"

Avaa Thunderbitin sivupalkki ja napsauta "AI Suggest Fields." AI lukee sivun ja ehdottaa automaattisesti sarakkeita: hinta, osoite, makuuhuoneet, kylpyhuoneet, neliöt, Zestimate, listaus-URL ja paljon muuta. Testeissäni se tunnistaa yleensä yli 20 kenttää ilman manuaalista asetusten tekemistä.

### Vaihe 3: Napsauta "Scrape"

Paina Scrape-painiketta. Data täyttyy jäsenneltyyn taulukkoon laajennuksen sisällä. Thunderbit käsittelee Zillow’n sivutuksen automaattisesti — sekä klikkauspohjaisen että jatkuvan vierityksen.

### Vaihe 4: Rikasta dataa alisivujen haulla

Haluatko yksityiskohtaisia tietoja, kuten verohistoriaa, kouluarvioita tai hintahistoriaa? Käytä "Scrape Subpages" -toimintoa taulukon rikastamiseen. Thunderbit käy jokaisen kohteen URL-osoitteen läpi ja poimii lisäkentät — ilman ylimääräistä koodia.

### Vaihe 5: Vie data

Vie tiedot Google Sheetsiin, Exceliin, Airtableen tai Notioniin. Vienti on ilmainen.

## Miksi Thunderbit toimii hyvin Zillow’n kanssa

Todellinen etu on kestävyys. Thunderbitin AI lukee sivun rakenteen tuoreeltaan joka kerta, kun haet dataa. Kun Zillow muuttaa asetteluaan (mikä tapahtuu usein), rikkoutuneita CSS-valitsimia ei tarvitse korjata. AI mukautuu automaattisesti. Tämä ratkaisee aidosti koodattujen scrapers-ratkaisujen "herkästi hajoavan" luonteen, joka turhauttaa niin monia käyttäjiä.

<VideoPlayer url={"https://www.youtube.com/watch?v=aViWT-WpzYI&ab_channel=WebScraper"} />

## Mitä dataa Zillow’sta voi poimia? (yli 20 kenttää)

Useimmat oppaat hakevat vain hinnan ja osoitteen ja pysähtyvät siihen. Zillow-listaukset sisältävät itse asiassa paljon enemmän poimittavaa dataa kuin moni arvaa — tässä hyödyllinen viitetaulukko:

<Table content={`| **Kenttä** | **Mistä se löytyy** | **Poiminnan vaikeus** |
|---|---|---|
| Listahinta | Haku + kohdesivu | Helppo |
| Osoite / postinumero | Haku + kohdesivu | Helppo |
| Zestimate | Haku + kohdesivu | Helppo |
| Hintahistoria (jokainen tapahtuma) | Kohdesivu | Vaikea (sisäkkäinen JSON) |
| Verohistoria | Kohdesivu | Vaikea (sisäkkäinen JSON) |
| Makuuhuoneet / kylpyhuoneet / neliöt | Haku + kohdesivu | Helppo |
| Rakennusvuosi | Kohdesivu | Helppo |
| Taloyhtiövastike | Kohdesivu | Keskitaso |
| Kävely- / joukkoliikenneluku | Kohdesivu (iframe) | Vaikea (vaatii JS-renderöinnin) |
| Kouluarviot | Kohdesivu | Keskitaso |
| Tontin koko | Kohdesivu | Helppo |
| Päiviä Zillow’ssa | Haku | Helppo |
| Välittäjä / toimisto | Haku + kohdesivu | Keskitaso |
| MLS-numero | Kohdesivu | Helppo |
| Kiinteistötyyppi | Haku + kohdesivu | Helppo |
| Leveys- ja pituusaste | \`__NEXT_DATA__\` JSON | Keskitaso |
| Kuvausteksti | Kohdesivu | Helppo |
| Kuvien URL-osoitteet | Haku + kohdesivu | Keskitaso |
| Rent Zestimate | Kohdesivu | Keskitaso |
| Lähialueen vertailukaupat | Kohdesivu | Vaikea |`} />

"Vaikeat" kentät — kuten hintahistoria, verohistoria ja vertailukaupat — sijaitsevat sisäkkäisessä JSONissa kohdesivuilla. Alla oleva Python-osio näyttää tarkalleen, miten ne poimitaan. Ja jos haluat mieluummin ohittaa koodin, Thunderbitin AI Suggest Fields tunnistaa automaattisesti useimmat näistä sarakkeista, ja Subpage Scraping hakee kohdesivujen kentät puolestasi.

## Python-ympäristön valmistelu Zillow’n hakemiseen

**Vaikeustaso:** Keskitaso  
**Aika:** noin 5 minuuttia asennukseen, noin 30 minuuttia koko opastukseen  
**Tarvitset:** Python 3.8+, Chrome-selaimen (sivujen tarkastelua varten), tekstieditorin tai IDE:n

Asenna tarvittavat kirjastot:

```bash
pip install httpx beautifulsoup4 pandas lxml

Näin kukin niistä toimii:

  • httpx — HTTP-asiakas, joka on nopeampi kuin requests ja tukee asynkronisuutta
  • beautifulsoup4 + lxml — HTML:n jäsentämiseen
  • pandas — datan vientiin CSV/Excel-muotoon
  • Valinnaisesti: selenium tai playwright, jos sinun täytyy renderöidä JavaScript-raskaita sivuja

Ymmärrä Zillow’n sivurakenne ennen kuin alat hakea dataa

zillow_structure_046e848770.png

Tämä on tärkein asia ymmärtää ennen kuin kirjoitat yhtään koodia. Zillow on Next.js-sovellus — tämän vahvistavat Zillow’n työntekijöiden engineering-postaukset. Se tarkoittaa, että suurin osa tarvitsemastasi datasta ei ole näkyvissä HTML-elementeissä. Se on upotettu <script id="__NEXT_DATA__">-JSON-lohkoon.

Avaa mikä tahansa Zillow’n kohdesivu, paina F12, siirry Elements-välilehdelle ja etsi __NEXT_DATA__. Löydät valtavan JSON-objektin, joka sisältää kaiken listausdatan — hinnat, koordinaatit, kohdetiedot, hintahistorian, verotiedot, kouluarviot ja paljon muuta.

Miksi tällä on väliä? Zillow’n CSS-luokat hashataan (styled-componentsin generoimina) ja ne muuttuvat jokaisessa julkaisussa. Luokka kuten StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0 saa ensi viikolla täysin erilaisen hashin. Mikä tahansa CSS-valitsimiin perustuva scraper rikkoutuu säännöllisesti.

__NEXT_DATA__-JSON-lähestymistapa on paljon vakaampi, koska se ei riipu HTML-rakenteesta lainkaan.

Keskeiset JSON-polut hakutuloksille:

Kohdesivuilla osa käyttää __NEXT_DATA__-rakennetta ja osa vaihtoehtoista hdpApolloPreloadedData-script-tunnistetta. Alla oleva koodi käsittelee molemmat.

Vaihe vaiheelta: näin poimit Zillow-dataa Pythonilla

Vaihe 1: Aseta HTTP-otsikot, jotta vältyt heti estetyksi tulemiselta

Pelkkä httpx.get()-kutsu Zillow’lle palauttaa listausdatan sijaan CAPTCHA-sivun. Zillow käyttää PerimeterX:ää (HUMAN Security) yhdessä Cloudflaren kanssa — molemmat on arvioitu 8/10 vaikeustasolle scraping-benchmarkeissa. Järjestelmä tarkistaa TLS-jäljen, HTTP-otsikot ja IP:n maineen.

Tässä ovat vähimmäisotsikot, jotka toimivat vuonna 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-otsikot ovat kriittisiä. Monet ohjeet jättävät ne pois — juuri siksi niiden koodi ei toimi PerimeterX:ää vastaan.

Vaihe 2: Hae Zillow’n hakutulokset

Zillow’n hakupolut noudattavat ennustettavaa rakennetta. Houstonissa, TX:ssä:

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

Jokaisella sivulla on noin 41 kohdetta. Zillow rajoittaa tulokset 20 sivuun (~820 kohdetta). Suurempiin aineistoihin sinun täytyy jakaa haku maantieteellisesti (siitä lisää myöhemmin).

Tässä koodi hakutulosten poimimiseen __NEXT_DATA__-JSONista:

from bs4 import BeautifulSoup
import json
import time
import random

def scrape_zillow_search(url):
    """Poimi listausdata Zillow’n hakutulossivulta."""
    response = httpx.get(url, headers=headers, timeout=15)

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

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

    if not script_tag:
        print("__NEXT_DATA__-lohkoa ei löytynyt — todennäköisesti CAPTCHA-eston takia")
        return []

    next_data = json.loads(script_tag.string)

    try:
        results = (
            next_data["props"]["pageProps"]["searchPageState"]
            ["cat1"]["searchResults"]["listResults"]
        )
    except KeyError:
        print("Odottamaton JSON-rakenne — Zillow on ehkä muuttanut formaattia")
        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

Jos haluat hakea useita sivuja, kierrä ne läpi viiveillä:

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

for page in range(1, 6):  # Ensimmäiset 5 sivua
    url = base_url if page == 1 else f"{base_url}{page}_p/"
    print(f"Haetaan sivua {page}...")

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

    # Satunnainen viive 3–7 sekuntia
    delay = random.uniform(3, 7)
    time.sleep(delay)

print(f"Poimittuja kohteita yhteensä: {len(all_listings)}")

Sinun pitäisi nähdä jäsenneltyä listausdataa kertymässä all_listings-muuttujaan. Jos tulos on tyhjä, tarkista alla oleva osio "Miksi scraperit rikkoutuvat".

Vaihe 3: Hae Zillow’n kohdesivujen yksityiskohtaiset tiedot

Hakutulokset antavat perusasiat. Kohdesivut sisältävät syvemmät tiedot: hintahistorian, verohistorian, kouluarviot, välittäjätiedot ja kohteen kuvauksen. Jokainen vaiheessa 2 löytyvä URL vie kohdesivulle.

Zillow’n kohdesivuilla on kaksi mahdollista dataformaattia. Tässä koodi, joka käsittelee molemmat:

def scrape_zillow_detail(url):
    """Poimi yksityiskohtaiset kohdetiedot Zillow’n listaus-sivulta."""
    response = httpx.get(url, headers=headers, timeout=15)

    if response.status_code != 200:
        return None

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

    # Kokeile ensin __NEXT_DATA__-rakennetta (yleisin)
    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

    # Vararatkaisu: 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):
    """Poimi jäsennellyt kentät Zillow’n kohde-JSONista."""
    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", [])
        ],
    }

Käy kohde-URL:t läpi viiveiden kanssa:

detail_data = []
for listing in all_listings[:10]:  # Aloita 10 kohteella testaukseen
    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"Haetaan kohdetta: {detail_url}")
    detail = scrape_zillow_detail(detail_url)

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

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

Tämän vaiheen jälkeen sinulla pitäisi olla sanakirjalista, joka sisältää sekä haku- että kohdetason tiedot jokaisesta kiinteistöstä.

Vaihe 4: Käsittele sivutus, jos haluat hakea useita sivuja

Alueilla, joilla on yli 820 kohdetta (20 sivun raja), tiedot täytyy jakaa maantieteellisesti. Zillow’n sisäinen API hyväksyy mapBounds-parametrit. Strategia on jakaa kartta neljänneksiin ja hakea kukin erikseen.

def split_bounds(bounds):
    """Jaa kartan rajat neljään osaan."""
    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"]},
    ]

Useimmissa käyttötapauksissa — kuten 50–200 kohteen hintaseurannassa tietyllä alueella — tavallinen URL-sivutus riittää. Neljännesjakoon perustuva tapa on tarkoitettu kaupunki- tai osavaltiotason massahakuihin.

Vaihe 5: Vie poimittu Zillow-data

Tallenna kaikki CSV-muotoon pandasilla:

import pandas as pd

df = pd.DataFrame(detail_data)
df.to_csv("zillow_houston_listings.csv", index=False)
print(f"Viety {len(df)} kohdetta tiedostoon zillow_houston_listings.csv")

JSON-vienti:

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

Jos haluat ohittaa vientivaiheen kokonaan, Thunderbit vie tiedot Google Sheetiin, Airtableen ja Notioniin ilmaiseksi — hyödyllistä, jos haluat datan heti yhteistyömuotoon.

Miksi Zillow-scraperit rikkoutuvat (ja miten rakennat kestäviä)

Tämä on selviytymisopas.

Kokemukseni mukaan Zillow-scraperit hajoavat kolmesta erityisestä syystä — ja jokaiselle on konkreettinen korjaus.

PerimeterX ja CAPTCHA:t: miksi pyyntösi palauttavat tyhjää dataa

Zillow’n PerimeterX-integraatio tarkistaa useita signaaleja yhtä aikaa: TLS-jäljen, HTTP-otsikot, IP:n maineen ja pyyntömallit. Kun se havaitsee automaation, se palauttaa listausdatan sijaan "Press & Hold" -CAPTCHA-sivun.

Tarkka vikatilanne: Lähetät pyynnön Pythonin oletusotsikoilla. Vastaus-HTML sisältää PerimeterX-haasteen skriptit kiinteistödatan sijaan — ja BeautifulSoup-haussa __NEXT_DATA__-tunnistetta ei löydy.

Korjaus: Käytä vaiheessa 1 esitettyjä täydellisiä selainotsikoita. Jos lähetät enemmän kuin muutaman kymmenen pyynnön, tarvitset myös proxy-kierrätystä (käsitellään alla). Raskaampaan hakuun kannattaa harkita kirjastoa kuten curl_cffi ja impersonate="chrome" — se on ainoa Pythonin HTTP-asiakas, joka pystyy vastaamaan aidon Chromen TLS-jälkeä.

Dynaamiset CSS-valitsimet: miksi BeautifulSoup palauttaa None-arvon

Jos käytät CSS-valitsimia kuten .list-card-price tai hashattuja luokanimiä, scraper rikkoutuu aina, kun Zillow julkaisee uutta koodia.

Zillow käyttää styled-componentsia, joka generoi luokanimiä kuten StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0. Hash-osa muuttuu jokaisessa buildissa.

Korjaus: Älä käytä CSS-valitsimia lainkaan. Poimi data __NEXT_DATA__-JSON-lohkosta kuten yllä olevassa koodissa. Tämä lähestymistapa on ollut vakaa vuosia, koska JSON-rakenne muuttuu paljon harvemmin kuin HTML-merkintä.

Jos HTML-jäsennystä on pakko käyttää, etsi data-test-attribuutteja (esim. data-test="property-card") tai käytä osittaista luokkamätsäystä kuten [class*="PropertyCard"]. JSON-poiminta on silti luotettavampi tapa.

Proxy-kierto ja eksponentiaalinen backoff: koodi, joka selviää IP-estoista

Zillow blokkaa datacenter-IP:t välittömästi. Luotettavaan käyttöön tarvitset residential-proxyt. Turvallinen tahti: 1 pyyntö per 3–8 sekuntia per IP, alle noin 500 pyyntöä tunnissa.

Tässä on retry-dekoraattori, jossa on eksponentiaalinen backoff ja jitter:

import random
import time

def backoff_with_jitter(attempt, base_delay=2, max_delay=60):
    """AWS-tyylinen täyden jitterin eksponentiaalinen 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"Estetty ({response.status_code}). Yritetään uudelleen {delay:.1f} s kuluttua...")
                time.sleep(delay)
                continue
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            time.sleep(backoff_with_jitter(attempt))
    return None

Ja yksinkertainen proxy-kiertopooli:

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)

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

Proxy-palveluntarjoajista DataImpulse tarjoaa residential-proxyt noin 1 $/GB hintaan (edullisin vaihtoehto), kun taas IPRoyal ja Smartproxy ovat vahvoja keskihintaisia vaihtoehtoja hintaluokassa 4–7 $/GB.

Nollaylläpidon vaihtoehto

Jos haet Zillow-dataa säännöllisesti ja kyllästyt rikkinäisten valitsimien korjaamiseen tai proxy-poolien hallintaan, Thunderbitin AI lukee sivun rakenteen uudelleen jokaisella haulla. Ei valitsimia ylläpidettäväksi, ei proxy-asetuksia. Se ratkaisee aidosti sen haavoittuvuuden, joka tekee koodatuista scrapers-ratkaisuista jatkuvan murheen.

Automatisoi Zillow-haku: ajastus ja hintaseuranta

Jokainen tuntemani kiinteistösijoittaja haluaa tämän, eikä mikään muu Zillow-hakuopas käsittele sitä: toistuvat automaattiset haut hintojen seuraamista varten.

Python-käyttäjille: cron-ajot ja hinnanmuutosten tunnistus

Aseta cron-tehtävä, joka ajaa scraperin viikoittain ja merkitsee hinnanmuutokset:

import pandas as pd
from datetime import datetime

def detect_price_changes(new_data, historical_file, threshold=0.05):
    """Vertaa uutta hakua historialliseen dataan ja merkitsee muutokset, jotka ylittävät kynnyksen."""
    try:
        old = pd.read_csv(historical_file)
    except FileNotFoundError:
        new_data.to_csv(historical_file, index=False)
        print("Ensimmäinen ajo — tallennettiin lähtötiedot.")
        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]

    # Lisää uudet tiedot aikaleiman kanssa
    new_data["scraped_at"] = datetime.now().isoformat()
    new_data.to_csv(historical_file, mode="a", header=False, index=False)

    return alerts

Lisää tämä crontabiin niin, että ajo tapahtuu maanantaisin klo 6.00:

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

Käytännön esimerkki: seuraa 50 Austinissa, TX:ssä sijaitsevan kohteen hintoja viikoittain. Joka maanantai skripti hakee tämänhetkiset hinnat, vertaa niitä edelliseen viikkoon ja tuottaa CSV:n, jossa korostuvat yli 5 %:n hinnanlaskut.

Ei-koodaajille: Thunderbit Scheduled Scraper

Thunderbitin Scheduled Scraperin avulla voit kuvata aikavälin omin sanoin ("joka maanantai klo 9"), syöttää Zillow-haku-URL:t ja klikata Schedule. Data viedään automaattisesti Google Sheetiin jokaisella ajolla. Ei Pythonia, ei cron-tehtäviä, ei palvelinta ylläpidettäväksi. Tämä on erityisen hyödyllistä kiinteistönvälittäjille tai operatiivisille tiimeille, jotka tarvitsevat säännöllistä hintaseurantaa ilman teknistä tukea.

Vinkkejä Zillow-datan vastuulliseen hakemiseen

Muutama huomio siitä, miten pysyt turvallisen rajan oikealla puolella:

  • Hae vain julkisesti saatavilla olevaa dataa. Älä käytä sivuja, jotka vaativat kirjautumisen tai tunnistautumisen.
  • Pidä pyyntötahti kohtuullisena. 3–8 sekuntia pyyntöjen välillä. Älä kuormita palvelinta.
  • Älä poimi henkilökohtaista tai yksityistä käyttäjätietoa. Listauksissa näkyvät välittäjän nimet ja toimistotiedot ovat julkisia; käyttäjätilitiedot eivät ole.
  • Säilytä ja käytä dataa eettisesti. Markkinatutkimus, sijoitusanalyysi ja liidien hankinta ovat hyväksyttäviä käyttötapoja. Spämmi ei ole.
  • Oikeudellinen tausta: hiQ v. LinkedIn -ratkaisu linjasi, että julkisesti saatavilla olevan datan hakeminen ei riko CFAA:ta. Meta v. Bright Data (2024) -ratkaisu vahvisti samansuuntaiset periaatteet. Zillow’n käyttöehdot kuitenkin rajoittavat automaattista pääsyä, ja he valvovat sitä IP-estoilla ja CAPTCHA:lla ennemmin kuin oikeustoimilla. Tarkista aina ajantasaiset ohjeet ja kunnioita robots.txt-tiedostoa.

Valitse oikea tapa hakea Zillow-dataa Pythonilla

Paras reitti riippuu tilanteestasi:

Tarvitset dataa nopeasti, ilman koodausta? Thunderbit vie sinut Zillow-hakutulossivulta jäsenneltyyn taulukkoon noin 2 minuutissa. AI mukautuu asettelumuutoksiin, hoitaa sivutuksen ja vie tiedot ilmaiseksi. Asenna Chrome-laajennus ja kokeile sitä Zillow’n hakusivulla.

Haluatko täyden hallinnan? Käytä tämän oppaan Python-koodia. Poimi data __NEXT_DATA__-JSONista (ei CSS-valitsimista) vakauden vuoksi. Aseta oikeat selainotsikot. Kierrätä residential-proxyt ja käytä eksponentiaalista backoffia luotettavuuden parantamiseksi.

Kasvatatko toimintaa? Scraping-API:t kuten ScrapFly (99 % onnistumisaste Zillow’ssa) tai ScraperAPI hoitavat proxy- ja CAPTCHA-infrastruktuurin puolestasi, hinnan ollessa 30–599 $/kk volyymista riippuen.

Seuraatko hintoja ajan yli? Ota käyttöön cron-ajo hinnanmuutosten tunnistusskriptillä tai käytä Thunderbitin Scheduled Scraperia ylläpitovapaana vaihtoehtona.

Data on olemassa. Ainoa kysymys on, kuinka paljon teknistä työtä haluat käyttää sen ulos saamiseen. Lisää vinkkejä verkkodatan viemisestä taulukoihin löydät oppaastamme datan poimiminen verkkosivuilta Exceliin tai Zillow-tilastoja kokoavasta katsauksesta, josta saat uusimmat alustatiedot. Voit myös katsoa ohjeita Thunderbitin YouTube-kanavalta.

<BottomCard url={"https://thunderbit.com/"} title={"Kokeile Thunderbitiä Zillow-datan poimintaan"} />

Usein kysytyt kysymykset

Voiko Zillow-dataa hakea Pythonilla ilmaiseksi?

Kyllä — httpx, BeautifulSoup ja pandas ovat kaikki ilmaisia ja avoimen lähdekoodin työkaluja. Vaihtokauppa on aika: sinun täytyy itse hallita otsikot, proxy-kierto ja valitsimien ylläpito. Varaudu 4–8 tunnin alkuasennukseen ja 4–10 tunnin kuukausittaiseen ylläpitoon, kun Zillow muuttaa sivustoaan. Thunderbit tarjoaa myös ilmaisen tason, jos haluat välttää koodauksen aiheuttaman lisätyön kokonaan.

Onko Zillow’lla virallinen API?

Zillow lopetti ilmaisen julkisen API:nsa syyskuussa 2021. Pääsy hoidetaan nyt Bridge Interactiven kautta, joka vaatii hyväksynnän, maksaa noin 500 dollaria kuukaudessa ja on suunnattu lisensoiduille kiinteistöalan ammattilaisille. Useimmille käyttäjille — sijoittajille, tutkijoille ja markkina-analyysiä tekeville välittäjille — scraping on käytännöllinen vaihtoehto. Zillow julkaisee silti myös ilmaisia tutkimusdatan CSV-tiedostoja osoitteessa zillow.com/research/data/, mukaan lukien Zillow Home Value Index ja Zillow Observed Rent Index.

Miten vältyn estetyksi tulemiselta Zillow-dataa hakiessa?

Kolme asiaa: (1) käytä realistisia selainotsikoita, mukaan lukien Sec-Ch-Ua — tämä on otsikko, jonka useimmat ohjeet unohtavat, ja jonka PerimeterX tarkistaa ensimmäisenä; (2) kierrätä residential-proxyt — datacenter-IP:t estetään heti; (3) poimi data __NEXT_DATA__-JSONista HTML-valitsimien sijaan, jotta asettelumuutokset eivät riko koodia. Pidä pyyntötahti 1 pyyntöön per 3–8 sekuntia per IP. Tai käytä työkalua kuten Thunderbit, joka hoitaa anti-bot-suojauksen automaattisesti.

Mikä on paras tapa hakea Zillow-dataa ilman koodausta?

Thunderbitin AI Web Scraper on nopein tapa. Asenna Chrome-laajennus, avaa Zillow’n hakutulos-sivu, napsauta "AI Suggest Fields" tunnistaaksesi sarakkeet automaattisesti, ja napsauta sitten "Scrape." Vie tiedot Google Sheetiin, Exceliin, Airtableen tai Notioniin ilman koodia. AI lukee sivun joka kerta uudelleen, joten se ei hajoa, kun Zillow päivittää asetteluaan.

Kuinka usein Zillow muuttaa sivustonsa rakennetta, ja miten se vaikuttaa scrapers-työkaluihin?

Zillow julkaisee päivityksiä usein — joskus viikoittain. Koska he käyttävät styled-componentsia, CSS-luokat muuttuvat jokaisen julkaisun yhteydessä, ja CSS-valitsimiin rakennetut scraperit hajoavat säännöllisesti. Kestävin Python-lähestymistapa on poimia data __NEXT_DATA__-JSON-lohkosta, jonka rakenne muuttuu huomattavasti harvemmin. Jos haluat täysin ylläpitovapaan vaihtoehdon, Thunderbitin AI lukee sivurakenteen uudelleen jokaisella haulla ja mukautuu automaattisesti asettelumuutoksiin.

Lue lisää

Shuai Guan
Shuai Guan
Thunderbitin toimitusjohtaja | AI:n ja tiedon automaation asiantuntija Shuai Guan on Thunderbitin toimitusjohtaja ja Michiganin yliopiston insinööritieteiden alumni. Lähes kymmenen vuoden kokemuksella teknologian ja SaaS-arkkitehtuurin parissa hän on erikoistunut muuttamaan monimutkaiset tekoälymallit käytännöllisiksi, koodittomiksi tiedon poimintatyökaluiksi. Tässä blogissa hän jakaa suodattamattomia, kentällä koeteltuja näkemyksiä verkkosivujen datan keruusta ja automaatiostrategioista, jotta voit rakentaa älykkäämpiä, dataohjautuvia työnkulkuja. Kun hän ei optimoi tietotyönkulkuja, hän hyödyntää samaa tarkkuutta myös valokuvauksen parissa.
Sisällysluettelo

Poimi verkkosivu pelkällä pyynnöllä

Kerro mitä tarvitset selkeällä englannilla. Tai vielä parempaa, älä kerro mitään.

Kokeile Thunderbitiä ilmaista
Poimi dataa AI:n avulla
Siirrä data helposti Google Sheetiin, Airtableen tai Notioniin
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week