Cara Scrape Zillow dengan Python (Tanpa Kena Blokir)

Terakhir diperbarui pada April 15, 2026
Cara Scrape Zillow dengan Python (Tanpa Kena Blokir)

Zillow menyimpan 160 juta catatan properti AS, dan mengambil data tersebut dalam skala besar adalah salah satu pekerjaan yang paling sering diminta — sekaligus paling bikin frustrasi — dalam pengolahan data properti. Kalau Anda pernah coba scrape Zillow lalu yang muncul malah halaman CAPTCHA, Anda jelas bukan satu-satunya.

Saya sudah menghabiskan banyak waktu untuk meneliti dan menguji berbagai pendekatan scrape Zillow — baik dengan Python maupun dengan alat no-code yang kami bangun di Thunderbit. Panduan ini membahas keduanya. Entah Anda ingin tutorial Python lengkap dengan strategi anti-bot, atau hanya butuh 200 listing masuk ke spreadsheet sebelum makan siang, ada bagian yang pas untuk Anda. Kita akan bahas kenapa data Zillow penting, bagaimana struktur situsnya di balik layar, tutorial Python langkah demi langkah, alasan kenapa scraper sering gagal, dan cara mengotomatiskan scraping berulang untuk memantau harga.

Kenapa Perlu Scrape Data Zillow?

Zillow adalah gudang data real estat residensial AS terbesar. Situs ini menarik 210 juta kunjungan per bulan dan menampung sekitar 750.000+ listing aktif untuk dijual serta 1,9 juta listing sewa. Platform ini menguasai lebih dari 50% traffic portal properti di AS — lebih dari dua kali kompetitor terdekatnya.

zillow_stats_998c14e590.png

Sebelum masuk ke kode Python, penting untuk tahu bahwa scrape Zillow dengan Python bukan satu-satunya opsi, dan salah pilih metode bisa buang waktu berjam-jam. Tools Python seperti httpx dan BeautifulSoup butuh skill menengah, pengelolaan header dan proxy secara manual, kecepatannya sedang (1–3 detik per halaman), dan perawatannya cukup sering, meski gratis; Selenium atau Playwright memperbaiki penanganan anti-bot dengan merender JavaScript, tetapi lebih lambat (5–15 detik per halaman) dan tetap butuh maintenance tinggi; scraping API seperti ScraperAPI atau ScrapFly lebih cepat dengan dukungan anti-bot bawaan dan maintenance sedang, tapi biayanya sekitar $30–599 per bulan; API resmi Zillow lewat Bridge Interactive cepat dan minim perawatan, tetapi terbatas dan biayanya sekitar $500 per bulan; sedangkan tools no-code seperti Thunderbit ramah pemula, cepat, tidak butuh maintenance berkat adaptasi AI, dan biasanya memakai model freemium.

Hemat waktu yang bisa didapat juga besar banget. Riset manual untuk 50+ kode pos bisa menghabiskan 15–20 jam per minggu. Scraping otomatis bisa menyelesaikan pekerjaan yang sama dalam hitungan menit — penghematan waktu sampai 99,7%.

Semua Cara Scrape Zillow: Python vs. API vs. No-Code (Perbandingan)

Sebelum masuk ke kode Python, ketahui bahwa "scrape Zillow dengan Python" bukan satu-satunya pilihan. Salah memilih metode bisa buang waktu berjam-jam. Berikut perbandingan langsung agar Anda bisa memilih sendiri:

MetodeTingkat KeahlianPenanganan Anti-BotKecepatanMaintenanceBiaya
Python + httpx/BeautifulSoupMenengahManual (header, proxy)Sedang (1–3 detik/halaman)Tinggi (selector sering rusak)Gratis
Python + Selenium/PlaywrightMenengahLebih baik (merender JS)Lambat (5–15 detik/halaman)TinggiGratis
Scraping API (ScraperAPI, ScrapFly)MenengahBawaanCepatSedang$30–599/bulan
API Resmi Zillow (Bridge Interactive)Pemula–MenengahN/ACepatRendah~ $500/bulan, akses terbatas
Tool No-Code (Thunderbit)PemulaBawaan (AI beradaptasi)CepatTidak ada (AI membaca ulang halaman)Freemium

Kalau Anda butuh data sekarang juga tanpa menulis kode, mulai dengan Thunderbit. Kalau Anda ingin paham alurnya atau butuh kustomisasi penuh, lanjut baca tutorial Python-nya.

Cara Paling Cepat: Scrape Zillow dengan Thunderbit (Tanpa Kode)

Sebelum masuk ke pembahasan Python yang lebih dalam, ini jalur yang cocok untuk siapa pun yang butuh data Zillow cepat — tanpa setup Python, tanpa konfigurasi proxy, tanpa maintenance selector. Kami membangun alur kerja ini di Thunderbit khusus untuk mengambil data properti terstruktur tanpa beban engineering.

Tingkat kesulitan: Pemula
Waktu yang dibutuhkan: ~2 menit
Yang dibutuhkan: Browser Chrome, Thunderbit Chrome Extension (versi gratis bisa digunakan)

Langkah 1: Install Thunderbit dan Buka Zillow

Pasang ekstensi Thunderbit dari Chrome Web Store. Buka halaman hasil pencarian Zillow — misalnya, cari rumah di Houston, TX.

Langkah 2: Klik "AI Suggest Fields"

Buka sidebar Thunderbit lalu klik "AI Suggest Fields." AI akan membaca halaman dan otomatis menyarankan kolom: harga, alamat, jumlah kamar tidur, kamar mandi, luas bangunan, Zestimate, URL listing, dan lain-lain. Dari pengujian saya, biasanya ia bisa mendeteksi 20+ field tanpa konfigurasi manual.

Langkah 3: Klik "Scrape"

Tekan tombol Scrape. Data akan langsung masuk ke tabel terstruktur di dalam ekstensi. Thunderbit menangani pagination Zillow secara otomatis — baik yang berbasis klik maupun infinite scroll.

Langkah 4: Perkaya dengan Scraping Subpage

Butuh data halaman detail seperti riwayat pajak, rating sekolah, atau riwayat harga? Gunakan "Scrape Subpages" untuk memperkaya tabel Anda. Thunderbit akan membuka setiap URL listing dan mengambil field tambahan — tanpa kode tambahan.

Langkah 5: Ekspor

Ekspor ke Google Sheets, Excel, Airtable, atau Notion. Ekspornya gratis.

Kenapa Thunderbit Cocok untuk Zillow

Keunggulan utamanya ada di ketahanan. AI Thunderbit membaca ulang struktur halaman setiap kali Anda melakukan scrape. Saat Zillow mengubah layout-nya (yang lumayan sering terjadi), tidak ada CSS selector rapuh yang harus diperbaiki. AI menyesuaikan secara otomatis. Ini benar-benar mengatasi sifat scraper berbasis kode yang memang rentan dan sering bikin pusing.

Data Apa Saja yang Bisa Diambil dari Zillow? (20+ Field)

Banyak panduan hanya ambil harga dan alamat, lalu berhenti. Padahal listing Zillow menyimpan jauh lebih banyak data yang bisa diekstrak — berikut tabel referensinya:

FieldLetaknyaTingkat Kesulitan Ekstraksi
Harga ListingPencarian + DetailMudah
Alamat / Kode PosPencarian + DetailMudah
ZestimatePencarian + DetailMudah
Riwayat Harga (setiap event)DetailSulit (JSON bertingkat)
Riwayat PajakDetailSulit (JSON bertingkat)
Kamar Tidur / Kamar Mandi / LuasPencarian + DetailMudah
Tahun DibangunDetailMudah
Biaya HOADetailSedang
Walk Score / Transit ScoreDetail (iframe)Sulit (perlu render JS)
Rating SekolahDetailSedang
Luas TanahDetailMudah
Hari di ZillowPencarianMudah
Agen Listing / BrokeragePencarian + DetailSedang
Nomor MLSDetailMudah
Jenis PropertiPencarian + DetailMudah
Latitude / LongitudeJSON __NEXT_DATA__Sedang
Deskripsi PropertiDetailMudah
URL FotoPencarian + DetailSedang
Rent ZestimateDetailSedang
Penjualan Komparabel TerdekatDetailSulit

Field yang "sulit" — riwayat harga, riwayat pajak, penjualan komparabel — tersimpan dalam JSON bertingkat di halaman detail. Bagian Python di bawah akan menunjukkan cara mengekstraknya. Kalau Anda mau melewati coding, AI Suggest Fields milik Thunderbit bisa mendeteksi sebagian besar kolom ini secara otomatis, dan fitur Subpage Scraping akan menarik field dari halaman detail tanpa perlu konfigurasi tambahan.

Menyiapkan Lingkungan Python untuk Scrape Zillow

Tingkat kesulitan: Menengah
Waktu yang dibutuhkan: ~5 menit untuk setup, ~30 menit untuk tutorial lengkap
Yang dibutuhkan: Python 3.8+, browser Chrome (untuk inspeksi halaman), text editor atau IDE

Install library yang diperlukan:

pip install httpx beautifulsoup4 pandas lxml

Fungsi masing-masing:

  • httpx — HTTP client dengan performa lebih baik daripada requests dan mendukung async
  • beautifulsoup4 + lxml — parsing HTML
  • pandas — ekspor data ke CSV/Excel
  • Opsional: selenium atau playwright kalau Anda perlu merender halaman yang sangat bergantung pada JavaScript

Memahami Struktur Halaman Zillow Sebelum Scrape

zillow_structure_046e848770.png

Ini adalah hal paling penting yang perlu dipahami sebelum menulis kode apa pun. Zillow adalah aplikasi Next.js — dikonfirmasi lewat posting engineering dari karyawan Zillow. Artinya, sebagian besar data yang Anda butuhkan tidak ada di elemen HTML yang terlihat. Data itu tertanam di blob JSON <script id="__NEXT_DATA__">.

Buka salah satu halaman properti Zillow, tekan F12, buka Elements, lalu cari __NEXT_DATA__. Anda akan menemukan objek JSON besar yang berisi semua data listing — harga, koordinat, detail properti, riwayat harga, catatan pajak, rating sekolah, dan lainnya.

Kenapa ini penting? Nama class CSS Zillow di-hash (dibuat oleh styled-components) dan berubah setiap kali deployment. Class seperti StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0 bisa punya hash yang sama sekali berbeda minggu depan. Scraper yang mengandalkan CSS selector akan sering rusak.

Pendekatan JSON __NEXT_DATA__ jauh lebih stabil karena sama sekali tidak bergantung pada struktur HTML.

Path JSON utama untuk hasil pencarian:

PathIsi
props.pageProps.searchPageState.cat1.searchResults.listResultsArray hasil pencarian
props.pageProps.searchPageState.cat1.searchResults.mapResultsHasil tampilan peta
props.pageProps.searchPageState.cat1.searchList.totalPagesTotal halaman yang tersedia

Untuk halaman detail, sebagian menggunakan __NEXT_DATA__ dan sebagian lagi memakai tag script alternatif hdpApolloPreloadedData. Kode di bawah menangani keduanya.

Langkah demi Langkah: Cara Scrape Zillow dengan Python

Langkah 1: Siapkan HTTP Headers agar Tidak Langsung Diblokir

Mengirim httpx.get() polos ke Zillow akan menghasilkan halaman CAPTCHA, bukan data listing. Zillow menggunakan PerimeterX (HUMAN Security) bersama Cloudflare — keduanya diberi tingkat kesulitan 8/10 oleh benchmark scraping. Sistem ini memeriksa TLS fingerprint, HTTP header, dan reputasi IP Anda.

Berikut header minimum yang bekerja per 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",
}

Header Sec-Ch-Ua sangat penting. Banyak tutorial melewatinya — itu salah satu alasan kenapa kode mereka tidak berhasil melawan PerimeterX.

Langkah 2: Scrape Hasil Pencarian Zillow

URL pencarian Zillow mengikuti pola yang dapat diprediksi. Untuk Houston, TX:

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

Setiap halaman berisi sekitar 41 listing. Zillow membatasi hasil sampai 20 halaman (~820 listing). Untuk dataset yang lebih besar, Anda perlu memecahnya berdasarkan wilayah geografis (akan dibahas nanti).

Berikut kode untuk scraping hasil pencarian dengan mengekstrak data dari JSON __NEXT_DATA__:

from bs4 import BeautifulSoup
import json
import time
import random

def scrape_zillow_search(url):
    """Scrape data listing dari halaman hasil pencarian Zillow."""
    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

Untuk scraping beberapa halaman, lakukan loop dengan jeda:

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

for page in range(1, 6):  # 5 halaman pertama
    url = base_url if page == 1 else f"{base_url}{page}_p/"
    print(f"Scraping halaman {page}...")

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

    # Jeda acak antara 3–7 detik
    delay = random.uniform(3, 7)
    time.sleep(delay)

print(f"Total listing yang berhasil di-scrape: {len(all_listings)}")

Anda seharusnya melihat data listing terstruktur terkumpul di all_listings. Kalau hasilnya kosong, cek bagian "Kenapa Scraper Sering Rusak" di bawah.

Langkah 3: Scrape Halaman Detail Properti Zillow

Hasil pencarian memberi dasar-dasarnya. Halaman detail berisi data yang lebih dalam: riwayat harga, riwayat pajak, rating sekolah, info agen, dan deskripsi properti. Setiap URL listing dari Langkah 2 mengarah ke halaman detail.

Halaman detail Zillow memiliki dua format data yang mungkin. Berikut kode yang menangani keduanya:

def scrape_zillow_detail(url):
    """Scrape data detail properti dari halaman listing Zillow."""
    response = httpx.get(url, headers=headers, timeout=15)

    if response.status_code != 200:
        return None

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

    # Coba __NEXT_DATA__ dulu (paling umum)
    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):
    """Ekstrak field terstruktur dari objek JSON properti Zillow."""
    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 melalui URL listing Anda dengan jeda:

detail_data = []
for listing in all_listings[:10]:  # Mulai dengan 10 dulu untuk tes
    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"Scraping detail: {detail_url}")
    detail = scrape_zillow_detail(detail_url)

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

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

Setelah langkah ini, Anda akan punya daftar dictionary yang berisi data level pencarian dan level detail untuk setiap properti.

Langkah 4: Tangani Pagination untuk Scrape Banyak Halaman

Untuk area dengan lebih dari 820 listing (batas 20 halaman), Anda perlu memecah berdasarkan wilayah. API internal Zillow menerima parameter mapBounds. Strateginya: bagi peta menjadi beberapa kuadran dan scrape masing-masing secara terpisah.

def split_bounds(bounds):
    """Bagi batas peta menjadi 4 kuadran."""
    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"]},
    ]

Untuk sebagian besar kasus — memantau 50–200 listing di area tertentu — pagination URL standar sudah cukup. Pendekatan kuadran dipakai untuk scraping skala kota atau negara bagian.

Langkah 5: Ekspor Data Zillow yang Sudah Di-Scrape

Simpan semuanya ke CSV dengan pandas:

import pandas as pd

df = pd.DataFrame(detail_data)
df.to_csv("zillow_houston_listings.csv", index=False)
print(f"Berhasil mengekspor {len(df)} listing ke zillow_houston_listings.csv")

Untuk ekspor JSON:

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

Kalau Anda ingin melewati proses ekspor sepenuhnya, Thunderbit bisa mengekspor ke Google Sheets, Airtable, dan Notion secara gratis — berguna kalau Anda ingin data langsung tersedia dalam format kolaboratif.

Kenapa Scraper Zillow Sering Rusak (dan Cara Membuatnya Lebih Tahan Banting)

Ini adalah panduan bertahan hidup.

Dari pengalaman saya, scraper biasanya rusak di Zillow karena tiga alasan spesifik — dan masing-masing punya solusi yang jelas.

PerimeterX dan CAPTCHA: Kenapa Request Anda Balasannya Kosong

Integrasi PerimeterX milik Zillow memeriksa beberapa sinyal sekaligus: TLS fingerprint, HTTP header, reputasi IP, dan pola request. Saat mendeteksi otomasi, sistem akan menampilkan halaman CAPTCHA "Press & Hold" alih-alih data listing.

Skenario kegagalan yang persis terjadi: Anda mengirim request dengan header default Python. HTML respons berisi skrip tantangan PerimeterX, bukan data properti — dan parse BeautifulSoup Anda tidak menemukan tag __NEXT_DATA__.

Solusinya: Gunakan header lengkap yang meniru browser dari Langkah 1. Kalau Anda mengirim lebih dari beberapa lusin request, Anda juga perlu rotasi proxy (dibahas di bawah). Untuk scraping berat, pertimbangkan library seperti curl_cffi dengan impersonate="chrome" — ini satu-satunya HTTP client Python yang bisa meniru TLS fingerprint Chrome asli.

Dynamic CSS Selectors: Kenapa BeautifulSoup Mengembalikan None

Kalau Anda memakai CSS selector seperti .list-card-price atau nama class dengan hash, scraper Anda akan rusak setiap kali Zillow melakukan deployment baru.

Zillow memakai styled-components, yang menghasilkan nama class seperti StyledPropertyCardHomeDetailsList-c11n-8-109-3__sc-1j0som5-0. Bagian hash-nya berubah setiap build.

Solusinya: Jangan pakai CSS selector sama sekali. Ambil data dari blob JSON __NEXT_DATA__ seperti pada kode di atas. Pendekatan ini stabil selama bertahun-tahun karena struktur JSON jauh lebih jarang berubah dibanding markup HTML.

Kalau memang harus memakai parsing HTML, cari atribut data-test (misalnya data-test="property-card") atau gunakan pencocokan class berbasis substring seperti [class*="PropertyCard"]. Tapi ekstraksi JSON tetap yang paling andal.

Rotasi Proxy dan Exponential Backoff: Kode yang Tahan IP Diblokir

IP datacenter langsung masuk daftar blokir oleh Zillow. Anda butuh residential proxy untuk akses yang lebih stabil. Rate aman: 1 request per 3–8 detik per IP, tetap di bawah ~500 request/jam.

Berikut decorator retry dengan exponential backoff dan 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"Diblokir ({response.status_code}). Mencoba lagi dalam {delay:.1f} detik...")
                time.sleep(delay)
                continue
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            time.sleep(backoff_with_jitter(attempt))
    return None

Dan pool rotasi proxy sederhana:

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)

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

Untuk penyedia proxy, DataImpulse menawarkan residential proxy sekitar ~$1/GB (opsi termurah), sementara IPRoyal dan Smartproxy adalah pilihan menengah yang solid di kisaran $4–7/GB.

Alternatif Tanpa Maintenance

Kalau Anda rutin scraping Zillow dan sudah bosan memperbaiki selector yang rusak atau mengelola pool proxy, AI Thunderbit membaca struktur halaman ulang setiap kali melakukan scrape. Tidak ada selector yang perlu dipelihara, tidak ada konfigurasi proxy. Ini benar-benar menyelesaikan masalah rapuhnya scraper berbasis kode yang sering jadi sumber pusing berulang.

Automasi Scraping Zillow: Penjadwalan dan Pemantauan Harga

Setiap investor properti yang pernah saya ajak bicara menginginkan ini, dan tidak ada panduan scraping Zillow lain yang membahasnya: scraping otomatis berulang untuk pelacakan harga.

Untuk Pengguna Python: Cron Job dan Deteksi Perubahan Harga

Atur cron job yang menjalankan scraper setiap minggu dan menandai perubahan harga:

import pandas as pd
from datetime import datetime

def detect_price_changes(new_data, historical_file, threshold=0.05):
    """Bandingkan hasil scrape baru dengan data historis, tandai perubahan > threshold."""
    try:
        old = pd.read_csv(historical_file)
    except FileNotFoundError:
        new_data.to_csv(historical_file, index=False)
        print("Run pertama — data baseline telah disimpan.")
        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]

    # Tambahkan data baru dengan timestamp
    new_data["scraped_at"] = datetime.now().isoformat()
    new_data.to_csv(historical_file, mode="a", header=False, index=False)

    return alerts

Tambahkan ini ke crontab untuk menjalankan setiap Senin pukul 6 pagi:

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

Contoh praktis: pantau 50 listing di Austin, TX setiap minggu. Setiap Senin, script mengambil harga terbaru, membandingkannya dengan minggu sebelumnya, lalu menghasilkan CSV yang menyoroti penurunan harga lebih dari 5%.

Untuk Non-Coder: Thunderbit Scheduled Scraper

Fitur Scheduled Scraper Thunderbit memungkinkan Anda menjelaskan interval dengan bahasa biasa ("setiap Senin pukul 9 pagi"), memasukkan URL pencarian Zillow, lalu klik Schedule. Data otomatis diekspor ke Google Sheets di setiap jadwal berjalan. Tanpa Python, tanpa cron, tanpa server untuk dirawat. Ini sangat berguna untuk agen properti atau tim operasional yang butuh pemantauan harga konsisten tanpa dukungan engineering.

Tips Scrape Zillow Secara Bertanggung Jawab

Beberapa catatan agar tetap berada di sisi yang aman:

  • Scrape hanya data yang tersedia untuk publik. Jangan akses halaman yang berada di balik login atau autentikasi.
  • Gunakan laju request yang wajar. Beri jeda 3–8 detik antar request. Jangan membombardir server.
  • Jangan scrape data pribadi/privat pengguna. Nama agen dan info brokerage pada listing adalah publik; data akun pengguna bukan.
  • Simpan dan gunakan data secara etis. Riset pasar, analisis investasi, dan lead generation adalah penggunaan yang sah. Spam bukan.
  • Konteks hukum: Putusan hiQ v. LinkedIn menetapkan bahwa scraping data yang dapat diakses publik tidak melanggar CFAA. Putusan Meta v. Bright Data (2024) mempertahankan prinsip serupa. Meski begitu, ToS Zillow membatasi akses otomatis, dan mereka menegakkannya lewat IP ban serta CAPTCHA, bukan lewat tindakan hukum. Selalu cek panduan terbaru dan hormati robots.txt.

Pilih Pendekatan yang Tepat untuk Scrape Zillow dengan Python

Jalur terbaik tergantung situasi Anda:

Butuh data cepat, tanpa kode? Thunderbit membawa Anda dari halaman pencarian Zillow ke spreadsheet terstruktur dalam sekitar 2 menit. AI menyesuaikan diri dengan perubahan layout, menangani pagination, dan mengekspor secara gratis. Pasang Chrome Extension dan coba di halaman pencarian Zillow.

Ingin kontrol penuh? Gunakan kode Python di panduan ini. Ekstrak dari JSON __NEXT_DATA__ (bukan CSS selector) untuk stabilitas. Set header yang meniru browser dengan benar. Rotasi residential proxy dan gunakan exponential backoff agar lebih andal.

Skala lebih besar? Scraping API seperti ScrapFly (tingkat keberhasilan 99% di Zillow) atau ScraperAPI akan menangani infrastruktur proxy dan CAPTCHA untuk Anda, dengan biaya $30–599/bulan tergantung volume.

Melacak harga dari waktu ke waktu? Buat cron job dengan script deteksi perubahan harga, atau gunakan Scheduled Scraper Thunderbit untuk pendekatan tanpa maintenance.

Datanya memang ada. Pertanyaannya cuma: berapa banyak waktu engineering yang ingin Anda habiskan untuk mengambilnya. Untuk informasi lebih lanjut tentang memasukkan data web ke spreadsheet, lihat panduan kami tentang scraping data dari website ke Excel atau ringkasan statistik Zillow untuk data platform terbaru. Anda juga bisa menonton tutorial di Thunderbit YouTube Channel.

Coba Thunderbit untuk Scraping Zillow Get Started Free

FAQ

Bisa tidak scrape Zillow dengan Python secara gratis?

Bisa — httpx, BeautifulSoup, dan pandas semuanya gratis dan open-source. Konsekuensinya adalah waktu: Anda harus mengelola header, rotasi proxy, dan maintenance selector sendiri. Perkirakan butuh 4–8 jam untuk setup awal dan 4–10 jam per bulan untuk maintenance saat Zillow mengubah situsnya. Thunderbit juga punya versi gratis kalau Anda ingin menghindari beban coding sepenuhnya.

Apakah Zillow punya API resmi?

Zillow menghentikan API publik gratisnya pada September 2021. Akses sekarang lewat Bridge Interactive, yang memerlukan persetujuan, biayanya sekitar $500/bulan, dan ditujukan untuk profesional real estat berlisensi. Untuk sebagian besar pengguna — investor, peneliti, agen yang melakukan analisis pasar — scraping adalah alternatif yang paling praktis. Zillow masih menerbitkan data riset gratis dalam bentuk CSV yang bisa diunduh di zillow.com/research/data/, termasuk Zillow Home Value Index dan Zillow Observed Rent Index.

Bagaimana cara menghindari blokir saat scraping Zillow?

Tiga hal: (1) gunakan header browser yang realistis termasuk Sec-Ch-Ua — ini header yang paling sering dilewatkan tutorial, dan ini yang pertama diperiksa PerimeterX; (2) rotasi residential proxy — IP datacenter langsung masuk daftar blokir; (3) ambil data dari JSON __NEXT_DATA__ alih-alih selector HTML agar tidak gampang rusak saat layout berubah. Jaga laju request di 1 per 3–8 detik per IP. Atau gunakan tool seperti Thunderbit yang menangani proteksi anti-bot secara otomatis.

Apa cara terbaik scrape Zillow tanpa coding?

Thunderbit AI Web Scraper adalah jalur tercepat. Pasang Chrome Extension, buka halaman pencarian Zillow, klik "AI Suggest Fields" untuk mendeteksi kolom otomatis, lalu klik "Scrape." Ekspor ke Google Sheets, Excel, Airtable, atau Notion tanpa perlu kode. AI membaca ulang halaman setiap kali, jadi tidak rusak saat Zillow memperbarui layout.

Seberapa sering Zillow mengubah struktur websitenya, dan apa dampaknya ke scraper?

Zillow sering merilis update — kadang mingguan. Karena mereka memakai styled-components, nama class CSS berubah setiap deployment, dan scraper yang dibangun di atas CSS selector sering rusak. Pendekatan Python yang paling tahan banting adalah mengekstrak dari blob JSON __NEXT_DATA__, yang strukturnya jauh lebih jarang berubah. Untuk pendekatan tanpa maintenance, AI Thunderbit membaca ulang struktur halaman setiap kali scrape dan menyesuaikan secara otomatis terhadap perubahan layout.

Pelajari Lebih Lanjut

Shuai Guan
Shuai Guan
CEO di Thunderbit | Ahli Otomasi Data AI Shuai Guan adalah CEO Thunderbit dan lulusan Teknik dari University of Michigan. Dengan pengalaman hampir satu dekade di bidang teknologi dan arsitektur SaaS, ia berfokus mengubah model AI yang kompleks menjadi alat ekstraksi data praktis tanpa coding. Di blog ini, ia membagikan wawasan apa adanya yang sudah teruji di lapangan tentang web scraping dan strategi otomasi untuk membantu Anda membangun alur kerja yang lebih cerdas dan berbasis data. Saat tidak sedang mengoptimalkan alur kerja data, ia menyalurkan ketelitian yang sama pada kecintaannya terhadap fotografi.
Daftar Isi

Ambil data halaman web cukup dengan bertanya

Cukup bilang apa yang kamu butuhkan dalam bahasa Inggris sederhana. Atau lebih baik lagi, tak perlu bilang apa-apa.

Coba Thunderbit gratis
Ekstrak Data menggunakan AI
Dengan mudah transfer data ke Google Sheets, Airtable, atau Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week