Article content and detailed guides remain in English. The selected language applies to controls and quick instructions.

Back to articles

Scraping Real Estate Listings for Business Intelligence and Leads

On this page

Real Estate Data Sources

Real estate generates large volumes of publicly available data. Understanding where data comes from and what access methods exist is essential for legal and effective data collection:

Data source What it contains Access method Legal considerations
MLS (Multiple Listing Service) Active, pending, sold listings with agent details Licensed access only (RETS/RESO Web API) Restricted to licensed agents and authorised vendors
County assessor / tax records Property ownership, assessed value, tax history County websites (public records) Public records; generally legal to collect
County recorder / deeds Sale prices, deed transfers, mortgage records County websites or in-person Public records
Zillow Listings, Zestimates, agent profiles No scraping (terms of service); limited API (deprecated) Terms prohibit scraping; use approved partnerships
Realtor.com Listings from MLS feeds No scraping (terms of service) Terms prohibit scraping
Redfin Listings, market data No scraping; some data downloadable (Redfin Data Center) Redfin Data Center offers free CSV downloads of market data
Apartments.com / CoStar Rental listings, commercial properties No scraping; CoStar API (commercial) Terms prohibit scraping; API access for partners
LoopNet Commercial real estate listings No scraping (CoStar-owned) Terms prohibit scraping
Public record APIs Standardised access to property records ATTOM Data, CoreLogic, Reonomy Paid API access; licensed data
Property auction sites Foreclosures, tax lien sales, auctions Auction.com, Hubzu, county auction sites Public listing data; check individual site terms
FHFA / Census data Housing price indices, demographic data Government websites Public data; free to use
Building permit records New construction, renovations City/county permit offices Public records
Consideration Details
MLS data is restricted MLS data is copyrighted by the MLS and licensed to members; scraping MLS data or sites that display it (like Realtor.com or agent IDX sites) violates MLS rules and likely copyright law
Terms of service Major platforms (Zillow, Realtor.com, Redfin, LoopNet) prohibit scraping in their terms of service
Public records are generally accessible County assessor, recorder, and property tax records are public records and are generally legal to collect
Fair Housing Act Do not use property data to target or exclude people based on protected characteristics
State real estate laws Some states restrict how property data can be used commercially
GDPR and privacy Property owner names and addresses may be personal data under GDPR for European properties
Copyright Listing descriptions, photos and MLS data are copyrighted; collecting factual data (prices, addresses) is different from copying creative content
Robots.txt Respect robots.txt directives even when data is publicly visible
Rate limiting Do not overload public record websites with rapid requests

What you can and cannot safely collect

Safe to collect Risky or restricted
Public property records (assessor, tax, deed) MLS listing data (copyrighted)
Publicly available sale prices Listing photos (copyrighted)
Permit and zoning records Listing descriptions (copyrighted)
Government housing data (Census, FHFA) Agent contact data from MLS-fed sites
Your own MLS data (if you are a licensed agent) Rental application data
Redfin Data Center downloads (offered by Redfin) Data behind authentication walls
Agent directory pages on brokerage websites Data from sites that prohibit scraping in ToS

Accessing Public Property Records

County assessor data

Most counties provide online access to property records. These are public records that include:

Data field Availability Use case
Property address All counties Property identification
Owner name Most counties Ownership research, direct mail targeting
Assessed value All counties Market analysis, valuation comparison
Tax amount All counties Tax analysis, affordability research
Property type Most counties Market segmentation
Square footage Most counties Comparable analysis
Year built Most counties Age of housing stock analysis
Lot size Most counties Land analysis
Sale date and price Most counties (some lag) Market trends, comparable sales
Zoning Most counties Development potential analysis
Legal description All counties Legal property identification

Python: Accessing county records APIs

Some counties and data aggregators provide APIs or bulk downloads:

import requests
import csv
import time

def fetch_property_records(county_api_url, params,
                            output_file):
    """Fetch property records from a county API endpoint."""
    results = []
    page = 1

    while True:
        params['page'] = page

        try:
            response = requests.get(
                county_api_url,
                params=params,
                timeout=30
            )
            response.raise_for_status()
            data = response.json()

            records = data.get('results', [])
            if not records:
                break

            results.extend(records)
            page += 1
            time.sleep(2)  # Polite rate limiting

        except requests.RequestException as e:
            print(f"Error on page {page}: {e}")
            break

    # Write to CSV
    if results:
        keys = results[0].keys()
        with open(output_file, 'w', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=keys)
            writer.writeheader()
            writer.writerows(results)

    return len(results)

Property data APIs (commercial)

Provider Data coverage Use case Pricing
ATTOM Data 155M+ US properties Property data, ownership, sales history, valuations Subscription; per-record pricing
CoreLogic Largest US property database Comprehensive property data, analytics Enterprise pricing
Reonomy Commercial real estate data CRE ownership, building data, tenant info Subscription
Estated Property data API Developer-friendly property lookups Per-call pricing
Plunk Property valuations and insights Automated valuations, renovation ROI API pricing
Regrid (Loveland) Parcel data and boundaries GIS, mapping, parcel identification Subscription
# Example: Using a property data API
import requests

def lookup_property(api_key, address, city, state):
    """Look up a property using a data API."""
    url = 'https://api.example.com/v1/property'
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Accept': 'application/json'
    }
    params = {
        'address': address,
        'city': city,
        'state': state
    }

    response = requests.get(url, headers=headers,
                             params=params, timeout=30)
    response.raise_for_status()
    return response.json()

Extracting Business Intelligence from Property Data

Market research applications

Analysis Data needed Insight produced
Price trend analysis Sale dates and prices by area Market direction; timing for buy/sell decisions
Inventory analysis Active listings count over time Supply trends; market tightness
Days on market analysis Listing date and sale date Market speed; pricing accuracy
New construction tracking Building permits, new listings Development activity; future supply
Foreclosure monitoring Pre-foreclosure filings, auction listings Distressed property opportunities
Rental yield analysis Rental prices vs property values Investment return analysis
Demographic overlay Census data + property data Neighbourhood characteristics; target market identification
Zoning change monitoring Zoning board records Development potential; land use changes

Lead generation applications

Lead type Data source How to identify
Absentee owners Tax records (mailing address differs from property address) Owner lives elsewhere; may be motivated to sell
Pre-foreclosure County recorder; lis pendens filings Owner facing foreclosure; time-sensitive
Probate / inherited properties Probate court records Heirs may want to sell quickly
Expired listings MLS data (if licensed) Seller still wants to sell; previous agent failed
Tax delinquent properties County tax records Owner struggling; may be motivated to sell
Long-term owners Purchase date in tax records Owners who bought 10-20+ years ago; significant equity
Vacant properties Utility records, code violations May indicate neglect; owner may sell
Recently permitted renovations Building permit records Owner investing in property; may be preparing to sell
Corporate-owned residential Tax records showing LLC/Corp ownership May be investment properties available for purchase
Downsizers Tax records showing elderly owners in large homes Life transition may trigger sale

Monitoring property data

import hashlib
import json
import os

def monitor_property_changes(records, previous_file):
    """Compare current records to previous snapshot
    and identify changes."""
    changes = {
        'new': [],
        'price_changed': [],
        'status_changed': [],
        'removed': []
    }

    # Load previous records
    previous = {}
    if os.path.exists(previous_file):
        with open(previous_file, 'r') as f:
            for record in json.load(f):
                key = record.get('address', '')
                previous[key] = record

    # Compare
    current_keys = set()
    for record in records:
        key = record.get('address', '')
        current_keys.add(key)

        if key not in previous:
            changes['new'].append(record)
        else:
            prev = previous[key]
            if record.get('price') != prev.get('price'):
                changes['price_changed'].append({
                    'address': key,
                    'old_price': prev.get('price'),
                    'new_price': record.get('price')
                })
            if record.get('status') != prev.get('status'):
                changes['status_changed'].append({
                    'address': key,
                    'old_status': prev.get('status'),
                    'new_status': record.get('status')
                })

    # Find removed listings
    for key in previous:
        if key not in current_keys:
            changes['removed'].append(previous[key])

    # Save current as new baseline
    with open(previous_file, 'w') as f:
        json.dump(records, f)

    return changes

Agent and Brokerage Directories

Real estate agent directories on brokerage websites are a source of contact information for B2B prospecting (selling services to agents, not for consumer outreach):

Source Data available Access
Brokerage websites Agent name, email, phone, photo, speciality Publicly listed on broker sites
State real estate commission Licensed agent directories State government websites (public record)
NAR (National Association of Realtors) Member directory realtor.com/realestateagents (public search)
Local Realtor associations Member directories Association websites

Ethical guidelines for agent data

Practice Guideline
Collect only publicly listed contact information Do not bypass authentication or access restricted areas
Respect robots.txt Follow robots.txt directives on brokerage sites
Rate limit requests Do not overload brokerage websites
Use data for B2B purposes Agent contact data is for business communication; follow CAN-SPAM
Do not resell scraped contact data Scraped data should not be commercially redistributed
Provide opt-out Include unsubscribe option in all outreach to agents

Processing Real Estate Data

When working with property data downloads (CSV from county assessor sites, HTML from public record searches, PDF from tax documents), upload to Email Extractor to extract email addresses. The tool handles CSV, HTML, PDF and other formats commonly used for property and agent data. This is useful for consolidating agent contact lists from multiple brokerage sites or extracting owner contact information from public record documents.

Extract emails

Explore tools

Verify emails

Check address validity before using your list.

ZeroBounce

Email Verification

Verifies email lists and provides tools for monitoring deliverability.

Useful when list cleaning and sender health belong in one workflow.

Explore ZeroBounce (opens in a new tab)