Use Zillow Research County Home Value Trend Scraper with Python
Get US county-level home value trends with 6- and 12-month comparisons and year-over-year percent change, plus a state-by-state home value comparison, from Zillow's published research files. Filter by state and county.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"homeType": "allHomesMidTier",
"maxItems": 3,
"mode": "stateTrends",
"sortBy": "sizeRank",
"state": "all"
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | required | What to return: one trend row per county, per state, per metro, or one history row per region per month. The legacy values keep old saved tasks working and are mapped to the matching trend mode. |
homeType | string | optional | Which Zillow Home Value Index series to read. All ten cuts are available at county, state, and metro level. |
state | string | optional | Filter counties, metros, or history to one state, or pick a single state in stateTrends. Choose 'all' to include every state. Two-letter codes are accepted by the API. |
county | string | optional | Case-insensitive county-name substring, e.g. 'Gallatin' or 'Los Angeles'. Works in countyTrends and county history. Use regionIds for exact matching. |
regionIds | array | optional | Exact Zillow RegionIDs, e.g. ['3101', '1090']. Works in every mode. When combined with state or county filters, a region must match all of them. |
asOfDate | string | optional | Compute the trend from the latest observation on or before this date (YYYY-MM-DD). Leave empty for the newest published month. Trend modes only. |
historyGeography | string | optional | Which ZHVI level the monthly history rows come from. Used only in history mode. |
startDate | string | optional | First month to include in history mode (YYYY-MM-DD). Leave empty to start at the oldest published month. |
endDate | string | optional | Last month to include in history mode (YYYY-MM-DD). Leave empty to end at the newest published month. |
sortBy | string | optional | Order trend rows and assign ranks across all matching regions before the row cap is applied. Missing metrics sort last without a rank. |
maxItems | integer | optional | Hard cap on emitted records. The default county file has 3,071 rows; history usually needs a date or region filter to stay under the cap. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/qP6Q9LcB74AQoCBmf/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
ZHVI trend records with true 1/3/6/12-month changes, benchmarks, and ranks, plus tidy monthly history observations.
Questions before you run
Which inputs are required?
The published required fields are mode
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build p7IgHPsuHr9v3aYYG and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.