Zillow Property Listings Scraper
Pricing
from $0.63 / 1,000 listing scrapeds
Zillow Property Listings Scraper
For-sale, for-rent and recently-sold property listings from Zillow search. One flat row per property: address, price, beds, baths, living area, lot size, home type, days on Zillow, coordinates, broker and photo.
Pricing
from $0.63 / 1,000 listing scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
One search in, one flat table out. Give it a location — a city, a ZIP, a county, or a Zillow search URL pasted from your browser — and it returns the properties Zillow would show you, each with its address, price, beds, baths, floor area, lot size, home type, days on Zillow, coordinates, listing broker and photo.
Covers all three Zillow tabs: for sale, for rent and recently sold.
Built to be called by an agent or a script: small input, small output, one row per property, no nested objects, no HTML.
Input
| field | meaning |
|---|---|
location | "Austin, TX", "90210", "Miami-Dade County, FL", or a full Zillow search URL |
listingType | forSale (default), forRent or sold |
maxResults | How many rows to return. Default 100, ceiling 820 — see below |
priceMin, priceMax | Price band. Asking price for sale and sold; monthly rent for rent |
bedsMin, bathsMin | Minimum bedrooms and bathrooms |
sort | Zillow default, newest, price, bedrooms, square feet or lot size |
requestIntervalSecs | Pause between result pages. Default 1 |
proxyConfiguration | Residential proxy. Required in practice — see below |
Pasting a Zillow URL keeps whatever filters are already on it — waterfront,
school rating, keyword, HOA — and applies the fields above on top. The one thing
a pasted URL does not override is listingType, because an input that loses
to a value hidden inside a URL is an input nobody can trust.
Output
One item per property:
| field | meaning |
|---|---|
zpid | Zillow's property id. Stable for a home; a lat--lng string for an apartment building |
url | The listing page on zillow.com, absolute |
address | Full address as Zillow renders it |
street_address, city, state, zipcode | The same address, split |
price | Asking price, monthly rent, or sale price, depending on listingType |
price_text | The same figure as Zillow renders it, e.g. "$3,455+" |
currency | Currency price is quoted in |
beds, baths | Bedroom and bathroom counts. Zillow counts a half bath as 0.5 |
living_area, living_area_unit | Interior floor area, sqft for US listings |
lot_size, lot_size_unit | Lot size, and the unit it was measured in — read both |
home_type | SINGLE_FAMILY, CONDO, TOWNHOUSE, MULTI_FAMILY, APARTMENT, LOT, … |
listing_status | FOR_SALE, FOR_RENT, SOLD, PENDING, … |
days_on_zillow | Days the listing has been live |
latitude, longitude | Coordinates |
broker_name | Listing brokerage |
image_url | First photo, full size |
zestimate, rent_zestimate | Zillow's own value and rent estimates |
year_built | Always null — see below |
is_building | true for an apartment building rather than a single home |
listing_type, search_location | The search this row belongs to, echoed back |
lot_size needs lot_size_unit
Zillow switches units by size: a suburban lot comes back as 6359.76 sqft
and a rural one as 2.4 acres. A pipeline that reads lot_size alone and
sorts on it will put the two-acre parcel below the townhouse. The unit always
travels with the number.
year_built is declared but never filled
Zillow's search endpoint does not carry it. The value lives only on each property's own detail page, which would be one extra request per row — a different, and much more expensive, product than this one. The column is kept so this dataset joins cleanly onto detail-page data; it is never guessed at.
Apartment buildings are nulls, not zeros
A for-rent search returns individual homes and whole apartment buildings. A
building has no single price, no bed count and no floor area, because it is a
container for units that each have their own. Those rows carry
is_building: true, null in the per-home fields, and the cheapest
advertised unit price in price with Zillow's own "$3,455+" string in
price_text.
A 0 there would read as "studio, no space, free", and any screen built on the
dataset would pick it up. Nothing in this output is ever zero to mean "unknown".
Limits worth knowing before you run it
- 820 rows per search, always. Zillow serves 41 listings per page and stops
paginating at 20 pages, whatever the match count.
total_availablein the run log tells you how many matched — it is routinely five figures. To collect more than 820, split the search: by ZIP, by price band, or by home type. - Residential proxy is required, not optional. Zillow refuses datacenter addresses, and is uneven even on residential ones — the same page answers HTTP 200 from one exit address and 403 from the next, minutes apart. The run answers a refusal by rotating to a fresh address and backing off with jitter rather than failing, which is what turns that unevenness into data. Turning the proxy off will produce blocks.
- Zillow's anti-bot page is an HTTP 200. It serves a "Press & Hold" page rather than an error status, so a status check alone would report success and return nothing. This actor treats a page with no data in it as a refusal and rotates, which is why a run can log retries and still come back complete.
Pricing
Pay per event: a small charge when the run starts, plus one charge per listing row delivered. Rows skipped as duplicates across page boundaries are not charged, and a run that returns nothing charges only the start event.