Property Listing Scraper avatar

Property Listing Scraper

Pricing

from $0.10 / 1,000 property listings

Go to Apify Store
Property Listing Scraper

Property Listing Scraper

Extract structured data from any real estate listing. Works with Zillow, Rightmove, Imobiliare, Idealista and more. Gets price, photos, bedrooms, area, coordinates, and agent details from any property page.

Pricing

from $0.10 / 1,000 property listings

Rating

0.0

(0)

Developer

Oaida Adrian

Oaida Adrian

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

2 days ago

Last modified

Share

Property Listing Scraper — Universal Real Estate Data Extractor

Extract clean, structured real estate data from any property website — Zillow, Rightmove, Idealista, Imobiliare, Realtor, Domain, or a local agency site you found this morning. Point it at a single listing or a whole search-results page and get back one tidy JSON item per property: price, location, size, rooms, and images.

No per-site templates to maintain. The scraper reads the structured data that modern property sites already embed (JSON-LD, microdata, OpenGraph) and falls back to smart HTML parsing, so it keeps working when a site changes its layout.

Why this Actor?

  • Works everywhere — one Actor for every portal instead of one brittle scraper per site.
  • Search-page aware — give it a search URL and it discovers and follows the individual listing links for you (up to maxListings).
  • Structured, null-tolerant output — every field is always present; missing values come back as null rather than breaking your pipeline.
  • Fast — up to 5 listings scraped concurrently.
  • No proxy setup — residential proxy is enabled by default so geo-restricted portals load reliably.

Who is this for?

  • Investors & analysts — build price-per-m² datasets across neighbourhoods and portals.
  • PropTech & aggregators — feed a normalised listing stream into your own app or database.
  • Agents & valuers — pull comparables from any market on demand.
  • Data / RAG pipelines — clean, typed property records ready for an LLM or analytics stack.

Input

{
"startUrls": [
{ "url": "https://www.rightmove.co.uk/property-for-sale/find.html?searchLocation=London" },
{ "url": "https://www.zillow.com/homedetails/123-Main-St/12345_zpid/" }
],
"maxListings": 50
}
FieldTypeDefaultDescription
startUrlsarrayrequiredListing pages or search-results pages
maxListingsint50Max listings to follow from each search page

Residential proxy is enabled by default to reach geo-restricted portals reliably.

Output (one item per property)

{
"id": "12345_zpid",
"title": "3-Bed Terraced House, Camden",
"price": 725000,
"currency": "GBP",
"address": "42 Example Road, London NW1",
"propertyType": "House",
"areaSqm": 96,
"bedrooms": 3,
"bathrooms": 2,
"images": ["https://.../photo1.jpg", "https://.../photo2.jpg"]
}
FieldTypeNotes
idstringSite's own listing ID when available
price / currencynumber / stringNormalised numeric price + ISO currency code
addressstringFull address as published by the site
propertyTypestringHouse, apartment, land…
areaSqmnumberArea in square metres (converted when the site uses sq ft)
bedrooms / bathroomsintCounts; null when the site doesn't publish them
imagesarrayDirect image URLs

Fields the site doesn't publish come back as null — never a wrong guess, and never a missing key.

Worked example

A run against an Austin, TX search page produced these real records (values trimmed):

[
{
"id": "20642605",
"title": "4 Bed Single Family Residence, 11204 Trelawney Ln",
"price": 695000,
"currency": "USD",
"address": "11204 Trelawney Ln, Austin, TX 78726",
"propertyType": "Single Family Residence",
"areaSqm": 222,
"bedrooms": 4,
"bathrooms": 3,
"images": ["https://.../photo.jpg"]
},
{
"id": "17420635",
"title": "3 Bed Townhouse, Riverside",
"price": 412000,
"currency": "USD",
"address": "8408 D-K Ranch Rd, Austin, TX 78744",
"propertyType": "Townhouse",
"areaSqm": 149,
"bedrooms": 3,
"bathrooms": 2,
"images": ["https://.../photo.jpg"]
}
]

Price is normalised to a plain number, currency is ISO-coded, and area is converted to square metres when the portal publishes square feet.

Run it on a schedule or from your app

curl -X POST "https://api.apify.com/v2/acts/darknezz~property-listing-scraper/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "startUrls": [{ "url": "https://www.idealista.com/venta-viviendas/madrid-madrid/" }], "maxListings": 100 }'

Python:

import requests
resp = requests.post(
"https://api.apify.com/v2/acts/darknezz~property-listing-scraper/runs",
params={"token": "YOUR_TOKEN"},
json={
"startUrls": [{"url": "https://www.rightmove.co.uk/property-for-sale/find.html?searchLocation=London"}],
"maxListings": 100,
},
timeout=300,
)
run_id = resp.json()["data"]["id"]

Schedule a daily run in the Apify Console to keep a market snapshot fresh, and pull new items from the dataset via the API.

Pricing

Pay per event — a small fee per property extracted. No subscription, no minimums: scrape one comparable or ten thousand listings and pay only for what you pull.

FAQ

Which sites are supported? Any property site that embeds standard structured data — that covers virtually every major portal (Zillow, Rightmove, Idealista, Realtor, Domain, Imobiliare, and thousands of regional sites). Unknown fields return null rather than a wrong guess.

Can I give it a search page instead of individual listings? Yes. The Actor detects search-results pages, follows the listing links, and scrapes each one up to your maxListings limit.

Do I need my own proxies? No. Residential proxy is configured by default so geo-restricted and bot-protected portals load reliably.

What if a listing is missing the price or area? The field comes back as null. Every output field is always present, so your downstream schema never breaks.

Is it fast enough for large markets? Up to 5 listings are scraped concurrently, and each search page's listing links are followed automatically — a 500-listing run typically finishes in a few minutes on standard Actor memory.

How does the parser stay current when sites change their markup? It reads the structured data modern portals already embed — JSON-LD, microdata and OpenGraph — and only falls back to HTML parsing when no structured block exists. When a site redesigns, the structured data usually stays, so the extractor keeps working without a code change.

Do search-page results carry full detail? Usually yes — most portals embed the full listing on the result card. A few portals render search pages with truncated cards, in which case some fields (notably price and title) can come back null on the first page until the detail page is reached. Re-running with the detail URL directly returns complete records.

What about geo-restricted or bot-protected portals? Residential proxy is enabled by default, which clears most geo-blocks. Portals behind aggressive anti-bot walls (JavaScript challenges, device fingerprinting) may still refuse datacenter egress; for those, running from a residential proxy group or a VPN-routed environment is the reliable path.

Limitations

  • Search-page completeness varies by portal. Detail pages always yield the full field set; search-result cards occasionally omit price/title on first render (see FAQ). The output schema is fixed and null-tolerant regardless.
  • Zip-code / postcode URLs are not supported as start URLs. Several portals (notably Redfin) route postcode searches through a region-id system that requires a challenge-answered session; use a city or neighbourhood search URL instead.
  • Concurrency is deliberate. Five concurrent requests keeps the actor polite to portals and avoids triggering rate-limit walls on large runs. If you need higher throughput, run multiple parallel runs against split URL lists.
  • id is the portal's own identifier when published. Portals that don't expose an ID get a stable hash of the listing URL instead.