Quick answer: Do not scrape Zillow's HTML. Zillow's Terms of Use explicitly prohibit automated data collection, and the site runs aggressive bot detection. The right way to get Zillow-adjacent real estate data is the official Bridge Interactive API (which exposes RESO-standard feeds), a direct MLS/RESO Web API feed, or public-record datasets. Those give you cleaner data and keep you out of legal trouble.
If you searched "scrape Zillow," you probably want listing details: price, beds, baths, square footage, address, days on market, maybe the Zestimate. I get it. But the honest answer is that hammering Zillow's pages is both against their rules and a bad engineering bet. Let me walk through what is actually available and how to build on it.
The Zillow Terms of Use Reality
Zillow's Terms of Use prohibit accessing the site with automated systems, copying content, and reproducing their data without permission. That includes scrapers, crawlers, and headless browsers pointed at consumer listing pages.
Beyond the contract, most of the interesting fields (the Zestimate, agent contact info, listing photos) are either Zillow's own intellectual property or sourced from an MLS under a licensing agreement Zillow signed. Republishing them can create copyright and licensing exposure that has nothing to do with whether your scraper technically worked.
So the question is not "how do I get past their bot detection." It is "where does this data legitimately come from, and can I get it at the source." Usually you can.
Official Option 1: Bridge Interactive API
Zillow Group owns Bridge Interactive, which provides API access to real estate data feeds. Bridge exposes data in the RESO Web API format (more on RESO below) and is the sanctioned way to work with Zillow Group data programmatically.
Access is gated. You typically need to be a licensed MLS member, a brokerage, or an approved technology partner, and the specific datasets you can pull depend on the agreements the source MLS has authorized. This is a feature, not a bug: it means the data you receive is licensed for your use.
Check current terms and onboarding on Bridge Interactive's developer site, since the available datasets and approval process change over time.
Official Option 2: RESO Web API and Direct MLS Feeds
Here is the thing most people miss: Zillow is not the source of listing data. The Multiple Listing Service (MLS) is. Zillow licenses feeds from MLSs and displays them.
If you are a licensed participant, you can often get a direct feed from the MLS itself using the RESO Web API, a standardized OData-based interface that most modern MLSs support. RESO also defines the Data Dictionary, a common schema so ListPrice, BedroomsTotal, and LivingArea mean the same thing across providers.
A direct RESO feed beats scraping in every way that matters:
| Approach | Data quality | Legal standing | Reliability |
|---|---|---|---|
| Scraping Zillow HTML | Parsed, fragile | Prohibited by ToS | Breaks on every redesign |
| Bridge / RESO Web API | Structured, standardized | Licensed | Stable OData contract |
| Public records | Authoritative for facts | Public domain | Varies by county |
Official Option 3: Public Records and Open Datasets
A lot of what people think of as "Zillow data" is actually public record: assessor valuations, parcel data, ownership, sale history, tax data. County assessor and recorder offices publish much of this, and many make it available as bulk downloads or APIs.
Public records will not give you the Zestimate or Zillow's live listing status, but for property facts and historical sales they are authoritative and free to use. For an aggregator, blending a licensed MLS feed with county public records covers most use cases.
When Fetching Public Pages Fits
There is a narrow, legitimate lane: pulling a small number of genuinely public pages that you have a right to read, at a respectful rate, where no official API exists. Think a public listing on a small independent brokerage site that has no feed, or a public government page.
That is different from bulk-harvesting Zillow. If you go this route, respect robots.txt, throttle hard, cache aggressively, and never bypass authentication or bot-protection challenges. For the ethics and boundaries here, see our guides on whether web scraping is legal and ethical web scraping best practices.
For those public-data-gap cases, link.sc can fetch a public URL and return clean markdown or structured JSON, so you are not maintaining a headless browser fleet for a handful of pages. Use it on data you are permitted to access, not to defeat protections.
A Code Sketch: RESO Web API First, Fetch as Fallback
Here is the shape of a compliant pipeline. The primary source is a RESO Web API feed (OData). The fallback fetch is only for permitted public pages where no feed exists.
import requests
# Primary: RESO Web API (OData) from your licensed MLS or Bridge feed.
RESO_BASE = "https://api.bridgedataoutput.com/api/v2/OData" # example base
RESO_TOKEN = "your-server-token"
def fetch_active_listings(city, min_beds=2):
params = {
"$filter": (
f"StandardStatus eq 'Active' "
f"and City eq '{city}' "
f"and BedroomsTotal ge {min_beds}"
),
"$select": "ListPrice,BedroomsTotal,BathroomsTotalInteger,"
"LivingArea,UnparsedAddress,DaysOnMarket",
"$top": 100,
}
r = requests.get(
f"{RESO_BASE}/Property",
headers={"Authorization": f"Bearer {RESO_TOKEN}"},
params=params,
timeout=30,
)
r.raise_for_status()
return r.json()["value"]
# Note: many real estate feeds use OAuth/Bearer tokens. That is fine.
# link.sc itself authenticates with the x-api-key header, not Bearer.
And the permitted-public-page fallback, using link.sc:
import requests
def fetch_public_page(url):
r = requests.post(
"https://api.link.sc/v1/fetch",
headers={"x-api-key": "lsc_your_key_here"},
json={"url": url, "format": "markdown"},
timeout=60,
)
r.raise_for_status()
return r.json()["content"]
Notice the two different auth styles. The RESO/Bridge feed uses Authorization: Bearer because that is how those APIs work. link.sc uses x-api-key. Do not mix them up.
Building the Aggregator
Once you have a licensed feed and public records, the interesting work is normalization, deduplication, and geocoding, not fighting a scraper. We wrote a full walkthrough of that architecture in build a real estate listings aggregator, including how to merge feeds from multiple sources into one clean schema.
Legal and Ethics Note
I am not your lawyer, and this is not legal advice. But the pattern is clear: Zillow's ToS prohibits scraping, much of the data is licensed from MLSs, and some fields are Zillow's own property. The compliant path (Bridge, RESO feeds, public records) exists precisely because the industry needs programmatic access. Use it. If a specific dataset requires MLS membership you do not have, partner with someone who has it rather than routing around the license.
The short version: get real estate data from the source, respect the licenses, and reserve fetching for genuinely public pages where no feed exists.
Ready to pull clean, structured data from the public web the right way? Start free with link.sc.