Zillow Property Listings Scraper avatar

Zillow Property Listings Scraper

Pricing

from $0.63 / 1,000 listing scrapeds

Go to Apify Store
Zillow Property Listings Scraper

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

Superslow Sloth

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

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

fieldmeaning
location"Austin, TX", "90210", "Miami-Dade County, FL", or a full Zillow search URL
listingTypeforSale (default), forRent or sold
maxResultsHow many rows to return. Default 100, ceiling 820 — see below
priceMin, priceMaxPrice band. Asking price for sale and sold; monthly rent for rent
bedsMin, bathsMinMinimum bedrooms and bathrooms
sortZillow default, newest, price, bedrooms, square feet or lot size
requestIntervalSecsPause between result pages. Default 1
proxyConfigurationResidential 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:

fieldmeaning
zpidZillow's property id. Stable for a home; a lat--lng string for an apartment building
urlThe listing page on zillow.com, absolute
addressFull address as Zillow renders it
street_address, city, state, zipcodeThe same address, split
priceAsking price, monthly rent, or sale price, depending on listingType
price_textThe same figure as Zillow renders it, e.g. "$3,455+"
currencyCurrency price is quoted in
beds, bathsBedroom and bathroom counts. Zillow counts a half bath as 0.5
living_area, living_area_unitInterior floor area, sqft for US listings
lot_size, lot_size_unitLot size, and the unit it was measured in — read both
home_typeSINGLE_FAMILY, CONDO, TOWNHOUSE, MULTI_FAMILY, APARTMENT, LOT, …
listing_statusFOR_SALE, FOR_RENT, SOLD, PENDING, …
days_on_zillowDays the listing has been live
latitude, longitudeCoordinates
broker_nameListing brokerage
image_urlFirst photo, full size
zestimate, rent_zestimateZillow's own value and rent estimates
year_builtAlways null — see below
is_buildingtrue for an apartment building rather than a single home
listing_type, search_locationThe 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_available in 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.