Zillow Scraper avatar

Zillow Scraper

Pricing

$1.00 / 1,000 results

Go to Apify Store
Zillow Scraper

Zillow Scraper

Extract public Zillow property details from listing URLs, addresses, and city search pages. Export prices, status, location, home facts, photos, listing attribution, and available history.

Pricing

$1.00 / 1,000 results

Rating

0.0

(0)

Developer

MLG Data

MLG Data

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

17 hours ago

Last modified

Share

Scrape Zillow property details from public listing URLs, street addresses, or city search pages. Export Zillow data to CSV, JSON, or Excel for pricing research, listing monitoring, and property comparisons. This actor is a practical Zillow API alternative for public listing information: a direct detail page can provide listing facts and attribution, while a search page can deliver a larger set of concise property records.

Each output row represents one property. The detailAvailable field tells you whether the actor reached its detail page. This distinction matters: property pages can show description, listing attribution, parking, and more photos, while search cards supply price, address, status, home type, beds, baths, area, and other summary facts. If a detail page is blocked, the actor retains the search card record instead of silently dropping the property.

What data can you extract from Zillow?

The dataset uses stable top level fields. Values depend on the property type, listing status, and what the public page exposes. An empty value does not imply the property lacks that characteristic. It means the relevant public page did not supply the field at collection time.

FieldDescriptionExample
zpidZillow property identifier.11026031
detailAvailableTrue when the property detail page was read; false when only search card data was available..true
propertyUrlCanonical property detail URL.https://www.zillow.com/homedetails/17-Zelma-Dr-Greenville-SC-29617/...
inputUrlURL requested for this property.https://www.zillow.com/homedetails/17-Zelma-Dr-Greenville-SC-29617/...
sourceSearchUrlSearch page that yielded the property, when applicable.null
listingStatusCurrent property status as reported on the page.FOR_SALE
homeTypeProperty type code.SINGLE_FAMILY
listingTypeHuman readable listing category.For Sale by Agent
isShowcaseListingWhether the property uses a showcase listing.false
isForSaleByOwnerWhether the property is listed by its owner.false
priceDisplayed property price in the listed currency.487500
currencyISO currency code.USD
priceChangeMost recent absolute price change.-7500
priceChangedAtDate of the most recent price change.2026-09-21
lastSoldPricePrice of the last sale when available.415000
zestimateEstimated property value when shown.478900
rentZestimateEstimated monthly rent when shown.2755
bedroomsBedroom count.4
bathroomsBathroom count.3
bathroomsFullFull bathroom count.3
bathroomsHalfHalf bathroom count.0
livingAreaInterior area in the displayed unit.2582
livingAreaUnitInterior area unit, usually square feet.null
yearBuiltYear of original construction.null
lotAreaValueNumeric lot area.0.5
lotAreaUnitLot area unit.Acres
lotSizeSqftLot size in square feet when provided.21780
pricePerSquareFootPrice divided by interior square feet when supplied.189
streetAddressStreet address.17 Zelma Dr
cityCity.Greenville
stateState abbreviation.SC
zipCodePostal ZIP code.29617
countryCountry.USA
fullAddressCombined public property address.17 Zelma Dr, Greenville, SC 29617
latitudeLatitude of the property.34.91575
longitudeLongitude of the property.-82.44426
neighborhoodNeighborhood or parent region.29617
timeZoneLocal time zone.America/New_York
descriptionPublic listing description.Public listing text
datePostedDate the listing was posted.2026-08-09
dateSoldDate of the last sale.2023-07-10
daysOnZillowDays the listing has been displayed.48
pageViewCountReported page views.984
favoriteCountReported saves or favorites.125
monthlyHoaFeeMonthly homeowners association fee.null
taxAssessedValueAssessed property tax value.null
propertyTaxRateProperty tax rate when shown.0.51
parkingSpacesTotal parking capacity.0
hasGarageWhether a garage is present.false
parkingFeaturesParking features listed in public facts.["Driveway", "Parking Pad"]
agentNamePublic listing agent name.Available when published
agentPhoneNumberPublic listing agent business phone.Available when published
agentEmailPublic listing agent business email when shown.Available when published
brokerNameListing brokerage name.Available when published
mlsIdListing identifier at the listing source.1600300
mlsNameName of the listing source.Available when published
photoCountReported number of photos.47
mainImageUrlMain listing photo URL.Available when published
photoUrlsPublic photo URLs when requested.["https://photos.zillowstatic.com/..."]
virtualTourUrlPublic virtual tour URL.Available when published
priceHistoryPrice history events exposed in the page payload.[]
scrapedAtUTC timestamp when the record was collected.UTC timestamp

The actor preserves numeric values as numbers rather than adding currency signs or units to them. price and currency can be used together for calculations. livingArea, lotAreaValue, and lotAreaUnit should be read together because acreage and square footage are different units. The priceHistory array is present only when exposed in the embedded detail data; an empty array does not mean there has never been a price change.

How to scrape Zillow

  1. Add one or more property detail URLs, a city search URL, or full street addresses. A typical property URL contains /homedetails/ and ends with a numeric _zpid identifier. A city search URL such as https://www.zillow.com/greenville-sc/ yields many candidate properties.
  2. Set maxItems to cap dataset records. For a city search, choose maxSearchPages and the desired propertyStatus. Start with one page and a modest item limit before expanding a collection.
  3. Leave enrichSearchResults enabled if you want the actor to open each property discovered on a search page. Turn it off if search card facts are sufficient or if the detail pages are heavily blocked. Direct property URLs are always opened as detail pages.
  4. Run the actor and open the dataset. Export the table as JSON, CSV, or Excel. Check detailAvailable before relying on description, agent, parking, or history fields.

The actor removes duplicate property identifiers within a run. If a direct URL and a search page point to the same property, only one row is saved. For a direct URL, the record contains inputUrl equal to the requested URL and sourceSearchUrl is empty. For properties discovered through a city page, sourceSearchUrl records that page.

Input

ParameterTypeDefaultDescription
startUrlsURL listEmptyPublic Zillow property detail or city search URLs.
addressesString listEmptyFull street addresses to resolve through public search results.
propertyStatusSelectANYFilter property cards expanded from a search page: any, for sale, for rent, or recently sold.
maxSearchPagesInteger1Maximum search result pages followed, up to 20.
maxItemsInteger100Maximum property rows saved. Set zero to remove the item cap.
enrichSearchResultsBooleantrueOpen property detail pages found in search results.
includePhotosBooleantrueInclude available photo URLs in photoUrls.
proxyConfigurationObjectEnabledConnection settings for remote requests.

A single direct property URL is the best input when you need all publicly exposed details for one listing. A city search URL is better when you need a table of comparable properties. Addresses are resolved by the site's public search path, which may redirect to a matching property. If an address is ambiguous, use a direct property URL to prevent a different match.

Example input for 30 for-sale records from a city search page:

{
"startUrls": [
{ "url": "https://www.zillow.com/greenville-sc/" }
],
"propertyStatus": "FOR_SALE",
"maxSearchPages": 1,
"maxItems": 30,
"enrichSearchResults": false,
"includePhotos": true
}

For detailed records, change enrichSearchResults to true or provide the detail URLs themselves. A search run can contain a mix of detailed and summary records because some detail pages may be blocked while the search page remains available. The field detailAvailable makes this visible per row.

Output example

The following selected fields came from a real detail record in the 30 item verification run on September 27, 2026. The listing description and photo list are shortened here for readability. The dataset includes every field listed above, including empty values.

{
"zpid": 11026031,
"detailAvailable": true,
"propertyUrl": "https://www.zillow.com/homedetails/17-Zelma-Dr-Greenville-SC-29617/11026031_zpid/",
"listingStatus": "FOR_SALE",
"homeType": "SINGLE_FAMILY",
"listingType": "For Sale by Agent",
"price": 487500,
"currency": "USD",
"priceChange": -7500,
"priceChangedAt": "2026-09-21",
"lastSoldPrice": 415000,
"zestimate": 478900,
"rentZestimate": 2755,
"bedrooms": 4,
"bathrooms": 3,
"livingArea": 2582,
"lotAreaValue": 0.5,
"lotAreaUnit": "Acres",
"fullAddress": "17 Zelma Dr, Greenville, SC 29617",
"latitude": 34.91575,
"longitude": -82.44426,
"datePosted": "2026-08-09",
"dateSold": "2023-07-10",
"daysOnZillow": 48,
"photoCount": 47,
"description": "Location doesn't get better than this!..."
}

That property had a detailed page available. A record from the same city search can show detailAvailable: false while still carrying zpid, status, price, address, home type, bedrooms, bathrooms, area, and estimates from the search card. Treat the two kinds of records differently when building a report that requires complete listing descriptions or attribution.

Use cases

  • Comparable listing research: collect active listings in a city, then group homes by location, property type, interior area, beds, and price. Use pricePerSquareFoot where the detail page supplies it, or calculate it from numeric price and area.
  • Price movement monitoring: schedule repeated runs for a stable set of detail URLs and compare price, priceChange, priceChangedAt, and listingStatus across dated datasets. A single run is a snapshot, not a historical archive.
  • Property intake: enter addresses or property URLs from a research list and standardize the output into fields suitable for a spreadsheet. Keep zpid as the matching key when refreshing records.
  • Rental and sale comparisons: use rentZestimate and zestimate where the site publishes them, alongside listed price and property facts. Estimates are site-provided values, not independent valuations.
  • Listing quality review: identify records with missing photos, description, construction year, or public attribution. Filter on detailAvailable before treating missing detail fields as a listing quality problem.
  • Geographic review: plot latitude and longitude for properties where the public listing discloses coordinates. Check fullAddress before sharing a location externally.

How much does it cost to scrape Zillow?

The configured dataset event price is $1 per 1,000 delivered property records, or $0.001 per saved row. The count refers to output records, not to every page request. A 30 row run has an event charge of about $0.03; 1,000 rows cost $1.00; and 5,000 rows cost $5.00 at that rate. Your account's live pricing page is the authority for any separate platform or proxy charges.

A search page can contain dozens of property cards, so enrichSearchResults: false can produce a larger dataset with fewer requests. When enrichment is on, each property detail request adds processing time. It does not add an extra result charge for the same property: a property identifier is written once. Residential proxy escalation can also make a blocked detail run more expensive to operate. Start with a smaller maxItems value to measure the actual run time and availability for your target area.

Tips for best results

Use precise property URLs when you need detail fields. The city search path is useful for discovery, but the public card has less information than a property detail page. A full street address with city, state, and ZIP is more reliable than a partial street name; the public resolver can redirect an ambiguous query to another property.

For a large city, set a small maxItems and maxSearchPages: 1 first. Search pages may expose a limited number of results and a finite number of anonymous pages. Increase maxSearchPages only if the initial output shows that your page and status combination yields useful results. The actor follows the search page's next link rather than inventing page numbers.

Check detailAvailable before deciding which fields to require. If it is false, the row came from embedded search card data. Price, status, address, home type, bed and bath count, interior area, coordinates, and estimates can still be present. Description, full photo sets, parking details, and source attribution usually require a detail page. For strict detail-only pipelines, keep only rows where detailAvailable is true and rerun blocked URLs separately later.

Use the date and unit fields carefully. datePosted, dateSold, and priceChangedAt are dates from the public page and can be empty. scrapedAt is the collection timestamp. lotAreaValue may be in acres while livingArea is in square feet. Do not add those measurements together or compare them without converting units.

Limits

The site may return a block page or a rate limit response, especially when many detail pages are opened in one run. The actor starts with a lower cost connection route, rotates the connection after repeated blocks, and may use a residential route when necessary. Search cards are saved as fallback when their detail pages cannot be read. Direct detail URLs have no search card fallback unless the same property also appears in a search input.

The search expander currently follows public city search pages and emits property detail records identified by a _zpid URL. Some rental search pages mostly return apartment or building pages with a different data structure; those entries are skipped. Community and building unit extraction are outside this version's verified scope. A result page can also return fewer rows than requested because of search page limits, duplicate property identifiers, unsupported result types, or blocked pages.

Not every listing publishes every field. A sold or off-market property may not have a current listing price, current agent, or current description. Some property layouts expose price history while others do not. A value may also change between runs as the listing changes. Use zpid, scrapedAt, and detailAvailable to compare snapshots responsibly.

Automated workflows

A scheduled workflow can collect a small city sample each morning and compare the new dataset to the previous day's dataset by zpid. For example: “Collect the first 30 for-sale properties in Greenville and report newly listed properties and price changes.” The comparison step should use the saved datasets because this actor returns the current page snapshot.

A second workflow can enrich a curated list of property URLs: “Open these 20 property detail links and return prices, bedroom counts, interior area, photos, and publicly displayed listing attribution.” Set maxItems to match the list length, then flag any row missing from the dataset for retry. Do not assume a blocked direct URL produced a summary record unless a search page also supplied it.

FAQ

Do I need a login?

No. The actor uses public pages. It does not read private account pages or require account credentials for the target site. Public availability still varies with status, location, and traffic controls.

Why is detailAvailable false?

The row was built from a public search card. This occurs when enrichSearchResults is disabled or when the detail page could not be read after connection retries. Core card fields remain useful, but detail-only fields may be empty.

Can I collect all results from a large city?

The actor follows up to 20 search result pages per run when they are available. The site can cap anonymous search results, and a city may contain more listings than those pages expose. Narrow inputs by city, status, or other public search pages if you need broader coverage.

Does an empty priceHistory mean no price changes?

No. It means the embedded page payload did not expose a history array for that record. The current priceChange and priceChangedAt fields may still be populated separately.

Can I export or schedule the data?

Yes. The dataset can be downloaded in JSON, CSV, and Excel formats and accessed through its dataset endpoint. Schedule repeated runs to maintain time snapshots. Compare them by zpid rather than by address text, which can be reformatted.

Is this data safe to reuse?

Only public page data is collected. Follow the site's terms and applicable privacy laws, and avoid using property or professional contact details for unwanted outreach. Decide the permitted use of the exported data for your project and location.

What if an address resolves to the wrong home?

Use the direct property URL. Address lookup relies on the site's public search redirect and may choose another match when the address is incomplete or ambiguous. Check propertyUrl, zpid, and fullAddress after a lookup.

Integrations

The dataset endpoint can feed reporting jobs, spreadsheets, scheduled comparisons, and webhook based workflows. A common pattern is to run the actor on a schedule, export the latest dataset, match rows by zpid, and write only changed prices or statuses to the destination. Keep the detailAvailable flag in downstream tables so analysts can distinguish a compact search record from a fuller property record.

Support

Open an issue on the Issues tab; we reply within 24h and add fields on request. Include a public property URL, the run date, and the field you expected. This makes it possible to distinguish a missing public field from a parser change or a temporary block.