Zillow Search Scraper

A property search on Zillow,
as rows with coordinates.

Type a place - Jacksonville, FL - or paste a Zillow search URL, and the listings come back as rows: the address, the price, beds, baths and square footage, the status, Zillow's own estimate, latitude and longitude, the place id, a link and an image.

one-time 500 free rows$0.002 per row after14 columnsCSV · XLSX · JSON
How it works

Name a place,
or paste a search.

This is the one Zillow service that is not about a person. Its three siblings all take an agent profile URL; this one takes a location or a search, and gives you properties.

  1. STEP 1Sign in to the platform.
  2. STEP 2Open the Zillow Search Scraper.
  3. STEP 3Type your searches - a place like Jacksonville, FL, or a zillow.com search URL - one per line, or upload a CSV, XLSX, TXT or Parquet file.
  4. STEP 4Choose a filter: For Sale, For Rent, Sold or All.
  5. STEP 5Set a limit per query, and a skip offset if you are paging past results you already have.
  6. STEP 6Point the run at a residential proxy, choose your output format and click Get Data.

One row per listing, tagged with the query it came from. Pages are fetched through our proxy pool rather than your real IP - but the pool alone is not enough here, which the section below explains.

Why teams use it

A market as a table,
not a map you scroll.

Coordinates on every row

Latitude and longitude populate on every row we have seen - including the ones where the place id is unusable - so the file maps as it lands, with no geocoding step and no address parsing.

Zillow's own estimate, next to the asking price

zestimate arrives as its own column alongside price, so the gap between what a property is listed at and what Zillow reckons it is worth is a subtraction rather than a research project.

A place name is a complete query

No URL to construct: Jacksonville, FL is a valid search on its own, and so is a Zillow search URL if you have already narrowed things down in the browser. Put a column of either in a file and the run works through the lot.

Read this before you build on it

Two things about this export
will bite you quietly.

The columns are straightforward. Two of their behaviours are not, and both are the kind that produce a wrong answer rather than an error.

The first is that home_type is always empty. It sits in the header row and carries nothing on any row we hold. What makes this worth a paragraph rather than a footnote is that the information is not missing - it is in the wrong column. status comes back as House for sale, Townhouse for sale, Condo for sale, so the property type is right there, glued to the listing state. If you need type as a field, parse it out of status; do not wait for home_type to fill.

The second is that this export mixes two kinds of row, and url is what tells them apart. A /homedetails/ row is an individual property: zpid is a numeric Zillow id, status is a listing state, and price, beds, baths, square footage and zestimate populate. A /apartments/ row is a whole rental community, and all three of those change at once - zpid holds a latitude–longitude pair instead of an id, status holds the community's name instead of a state, and price, beds, baths, sqft and zestimate are all empty. We checked that those three symptoms land on exactly the same rows, and they do. Split on url before you join on zpid or filter on status, or you will be mixing buildings into a table of homes without noticing.

Beyond those two, the formatting is predictable. price, zestimate and sqft are bare digit strings - 340000, not $340,000 - so they cast cleanly but carry no currency or units. beds and baths are single digits in what we hold, with no half-baths, though that may be a property of this sample rather than a guarantee. latitude and longitude populate everywhere, which is what saves the apartment rows: even when the id is unusable, the row still maps. Everything is a string except position, which is JSON-only.

Data dictionary

Fourteen columns in the file,
fifteen in the JSON.

The export's header row, in order. Where a field is described as sometimes empty, that is what the populated runs actually show - not a gap in the scrape.

query
The search you submitted, repeated on every row it produced - a place name like Jacksonville, FL, or the Zillow search URL you pasted.
address
The property's address, as one line. On a /homedetails/ row it carries a postcode; on an /apartments/ row it is the community's street address and generally does not.
price
The listed price, as a bare digit string - 340000, with no currency symbol and no thousands separator.
beds
Bedroom count, as a string. Single digits in our runs, with no half-values. Empty on /apartments/ rows.
baths
Bathroom count, same shape and same caveat. We have not seen a half-bath, but that may be this sample rather than a rule - do not assume the column is always an integer.
sqft
Floor area, again a bare digit string with no unit attached. Empty on /apartments/ rows.
home_type
See the note below.
status
Two different things live in this column. On a /homedetails/ row it is a listing state with the type attached - House for sale, Townhouse for sale, Condo for sale, Sold, Active. On an /apartments/ row it is the name of the rental community instead. Check url before you filter on this.
zestimate
Zillow's own valuation estimate, in the same bare-digit format as price. Sometimes absent on property rows and always absent on /apartments/ rows, so treat it as optional.
latitude
The property's latitude, as a string. Populates on every row we hold, including the apartment rows.
longitude
The longitude, likewise. With latitude this is what lets the file go straight onto a map - and it is the one geographic key that works on both kinds of row.
zpid
Not always an id. On a /homedetails/ row this is Zillow's numeric place id and makes a good stable key - though not a fixed-width one. On an /apartments/ row it holds a latitude–longitude pair instead, like 30.195362--81.72241. Size any column for it generously, and do not join on it blind.
url
The listing on Zillow - and the column that tells the two row types apart. /homedetails/ means an individual property; /apartments/ means a rental community. Split on this first and the rest of the file behaves.
image
A photo for the listing, on Zillow's image host. Populates on every row we hold.
position
1-based rank within the query, in the order Zillow returned the listing. JSON only - the CSV and XLSX exports stop at fourteen columns.

Two things to know before you build on this. First, home_type never fills - but the type is not lost, it is inside status (House for sale, Condo for sale), so parse it out of there. Second, the file holds two kinds of row and url is the discriminator: /homedetails/ rows are individual properties with a numeric zpid, a listing state in status and the price fields populated, while /apartments/ rows are whole rental communities where zpid is a latitude–longitude pair, status is the community's name, and price, beds, baths, sqft and zestimate are all empty. Those three symptoms occur on exactly the same rows. Beyond that: prices and areas are bare digit strings with no symbols or separators, latitude and longitude populate on every row so the file always maps, and position exists only in the JSON - so a CSV or XLSX export has fourteen columns rather than fifteen.

What it accepts

A place, or a search -
not an agent.

The one Zillow service here that does not take a profile URL. Give it somewhere to look and, if you want, a filter and an offset.

Jacksonville, FL https://www.zillow.com/jacksonville-fl/sold/ CSV · XLSX · TXT · Parquet upload Filtering: For Sale · For Rent · Sold · All Limit per query, or 0 for everything Skip offset, for paging One row per listing Datacenter IPs blocked - residential proxy required
Common workflows

Three jobs people
most often run here.

A few examples of what a market is worth once it is a table with coordinates on every row.

Pricing

Compare asking prices against Zillow's estimate

price and zestimate arrive as separate columns, so the spread is one subtraction away. Filter to For Sale, keep the /homedetails/ rows, and the over- and under-priced ends of a market fall out of the file.

Investment · Valuation
Mapping

Plot a whole market without geocoding

Every row carries latitude and longitude, so the export goes onto a map as it lands. Group by the type you parsed out of status for a picture of what is selling where, at what price, in what kind of property.

GIS · Market research
Tracking

Watch what actually sold, not what was listed

Set the filter to Sold, or paste a Zillow sold-search URL - in our runs that produced Sold statuses throughout. Re-run on a schedule and the zpid on the property rows gives you a stable key to diff against.

Analysis · Reporting
Pricing

Pay only for the listings
you actually pull.

No subscription, no minimum, no recurring bill. Your first 500 rows are on us - after that, pay-as-you-go at the same flat rate as every other scraper here.

Free tier

500 free rows - $0

Every new account, one-time. No credit card required. Per-query limits, filtering, the skip offset, file upload and every export format included. The residential proxy this scraper needs is yours to supply, on the free tier and after it.

$0 forever
Pay-as-you-go

$0.002 per row, after the free tier

The same flat rate as every other scraper on the platform. The pre-flight estimator shows the row count and credit cost before a run starts - no surprise bills, no compute units to translate.

Most popular
Volume

Custom · high volume

Volume pricing, dedicated workers and an SLA for tracking many markets on a schedule. Tell us your numbers and we will quote.

Talk to us
10% off your first paid run.Use code LIVESCRAPER10 at checkout.
Sign up
Pairs well with

The properties here,
the people next door.

This one returns listings. Our other three Zillow services all take an agent profile URL instead - and the fourth link is the same question on a different market.

The legal bit

Is it legal to scrape
Zillow listings?

Short answer: this is the lightest of our four Zillow exports on the privacy side - nobody is named in it - but Zillow's own terms are still the part that governs.

Everything in these fourteen columns is shown on a public Zillow search result to any visitor, signed in or not: the address, the price, the size, the status, Zillow's estimate, the coordinates and a photo. No login is used, no paywall is crossed and no account is touched, and the run is fetched through our proxy pool rather than your own IP.

No person is named anywhere in this export. There is no agent, no owner and no reviewer column - it is properties and prices. That is a genuine difference from our Zillow reviews export, which names the people who wrote the reviews, and from our Zillow agents export, which carries a named professional's phone number and licence. If your work only needs the market rather than the people in it, this is the one to reach for, and the data-protection questions are correspondingly lighter.

That is not the same as permission. Zillow's terms of use restrict automated access to their site, and the datacenter-IP blocking is there because they mean it - "the page is public" is an argument about the data, not about the contract you accept by using the site. Read those terms and decide whether your use is consistent with them before you scale a run. We run no third-party trackers on the data layer, and your exports auto-delete after 30 days.

livescraper.app · principles
Public search results only
No logins, no accounts touched
Never your real IP
Properties and prices - nobody is named
Exports auto-delete (30 days)
Check Zillow's own terms before scaling.
Common questions

Things people
ask before signing up.

The questions we hear most. Anything else? Talk to us - humans, not bots, write the answers.

How do I scrape Zillow listings?+
Using the Zillow Search Scraper: sign in to the platform, open the Zillow Search Scraper, type your searches - a place like Jacksonville, FL, or a zillow.com search URL - one per line (or upload a CSV, XLSX, TXT or Parquet file), choose a filter of For Sale, For Rent, Sold or All, set a limit per query and a skip offset if you need one, then point the run at a residential proxy, choose your output format and click Get Data.
What can I use as input?+
Either a place name or a Zillow search URL - both work, and both appear in the runs we hold. Jacksonville, FL is a complete query on its own, and so is a URL like https://www.zillow.com/jacksonville-fl/sold/ if you have already narrowed things down in the browser. Paste them one per line or upload a file with a column of them. Note that this is the one Zillow service that does not take an agent profile URL.
Why is the home_type column always empty?+
Because it never fills - it is in the header row of every export we hold and carries nothing on any row. The information is not lost, though: the property type is inside status, which comes back as House for sale, Townhouse for sale or Condo for sale. If you need type as its own field, parse it out of status rather than waiting for home_type.
Why do some rows have no price, beds or baths?+
Because they are not individual properties. This export mixes two kinds of row and the url column tells them apart: a /homedetails/ URL is a single property, while an /apartments/ URL is a whole rental community. On the community rows, price, beds, baths, sqft and zestimate are all empty - a building does not have one price or one bedroom count. Split on url before you do anything else and the file behaves.
Can I use zpid as a join key?+
On the property rows, yes - it is Zillow's numeric place id and it is stable across runs. On the rental-community rows it is not an id at all: it holds a latitude–longitude pair like 30.195362--81.72241. That means a blind join on zpid silently mixes two different kinds of key. Filter to /homedetails/ rows first, and size any database column for it generously, because it is not fixed width even among the numeric ones.
What format are the prices in?+
Bare digit strings. price, zestimate and sqft come back as 340000 rather than $340,000 - no currency symbol, no thousands separator and no unit. That makes them easy to cast, but it also means the file itself does not tell you the currency or whether sqft is square feet; both come from the market you searched.
Do I need a residential proxy?+
Yes. Zillow blocks datacenter IPs, and most of the runs we hold for this service came back with the fourteen-column header and no rows underneath. The ones that did return data are why this page can describe real cell contents at all. A run without a residential exit does not error - it completes and hands you an empty file - so check the proxy before you conclude that a market has no listings.
Is it legal to scrape Zillow listings?+
This is the lightest of our four Zillow exports on the privacy side: no person is named anywhere in the fourteen columns, so there is no agent, owner or reviewer to worry about - it is properties and prices. What still governs is Zillow's terms of use, which restrict automated access to their site. Read them and decide whether your use is consistent with them before you scale a run.
How much does it cost?+
The first 500 rows are free and one-time, with no credit card. After that it is $0.002 per row - the same flat rate as every other scraper on the platform. The estimator shows the cost of a run before it starts. The residential proxy is a separate cost, and it is on you.

Turn a place name
into a market you can map.

Your first 500 rows are free - no card, no subscription. After that it is $0.002 per row, flat.

Activates instantly · no card required

Scrape Zillow property search results

The Zillow Search Scraper turns a property search into rows. The input is either a place - Jacksonville, FL - or a zillow.com search URL, pasted one per line or uploaded as a CSV, XLSX, TXT or Parquet file, and every listing comes back as a record with the address, the price, beds, baths and square footage, the status, Zillow's own zestimate, latitude and longitude, the place id, a link to the listing and a photo. Fourteen columns in the file and fifteen in the JSON, one row per listing. A Filtering control narrows the run to For Sale, For Rent, Sold or All, and a Skip offset lets you page past results you already have. This is the one Zillow service of ours that does not take an agent profile URL - its three siblings all do.

Two properties of this export are worth knowing before you build on it, because both produce a wrong answer rather than an error. The first is that home_type is always empty. It is present in the header row and carries nothing on any row we hold - but the type itself is not missing, it is embedded in status, which comes back as House for sale, Townhouse for sale or Condo for sale. Parse it out of there rather than waiting for the dedicated column to fill.

The second is that the file mixes two kinds of row, and url is the discriminator. A /homedetails/ URL means an individual property: zpid is Zillow's numeric place id, status is a listing state, and price, beds, baths, sqft and zestimate populate. An /apartments/ URL means a whole rental community, and three things change together - zpid holds a latitude–longitude pair instead of an id, status holds the community's name instead of a state, and the price and size fields are all empty. Those symptoms occur on exactly the same rows, so splitting on url first is what keeps a join on zpid or a filter on status honest. Beyond that the formatting is predictable: price, zestimate and sqft are bare digit strings with no currency symbol or separators, and latitude and longitude populate on every row, so the export maps without a geocoding step even where the id is unusable.

One operational note and one legal one. Zillow blocks datacenter IPs, so a live run needs a residential proxy; without one the job still completes and hands you the header row with nothing beneath it, which reads as a market with no listings. And on the legal side this is the lightest of our four Zillow exports - no agent, owner or reviewer is named anywhere in the fourteen columns, so it is properties and prices rather than people. What governs is Zillow's terms of use, which restrict automated access; read them before you scale. Start free: your first 500 rows cost nothing and need no credit card, and after that it is $0.002 per row, flat, with the residential proxy as a separate cost.