Zoopla Property Scraper (UK) avatar

Zoopla Property Scraper (UK)

Pricing

from $0.56 / 1,000 results

Go to Apify Store
Zoopla Property Scraper (UK)

Zoopla Property Scraper (UK)

Scrapes property listings for sale or rent from Zoopla, the UK's #2 property portal. Search by location, property type and price/bedroom filters; returns price, address, coordinates, features and agent from a single search call, with an optional detail pass.

Pricing

from $0.56 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Scrapes property listings for sale or rent from Zoopla — the UK's #2/#3 property portal. UK coverage in this portfolio was OnTheMarket only; this adds a second, larger source (Rightmove, the #1 portal, blocks ClaudeBot/CCBot in robots.txt and was not pursued).

Public data only. No login, no cookies, no browser.

The one thing you need to know before using this

Zoopla sits behind a Cloudflare managed challenge. Two TLS profiles (chrome99_android, edge101) are blocked deterministically and excluded from the pool entirely; the remaining profiles are challenged intermittently (roughly 1 in 3–4 requests). The client retries with a rotated profile on every challenge — this is normal, expected traffic for this target, not a sign something is broken. Give it a real retry budget (the default maxConcurrency/minRequestInterval already do this) rather than lowering concurrency to "fix" occasional log warnings.

Rendering is Next.js App Router RSC streaming (self.__next_f.push(...)), not __NEXT_DATA__ — same protocol family as boligsiden-properties-scraper and justjoinit-jobs-scraper elsewhere in this portfolio. See CRAWLING_METHOD.md for the full trail.

What you get

Three record types share one dataset, told apart by recordType.

PROPERTY — one row per listing

Search rows (listing) already carry price, full address, coordinates, title, features, tags, photo gallery and the listing agent/branch. Turn on Fetch listing detail pages to also attach propertyDetail, which adds floor area, bed/bath counts, tenure, EPC, nearby stations and price history — none of which are present in search results.

SEARCH_SUMMARY — one row per (section, property type, location) query

Pages fetched, rows returned, upstream's own totalResults, and segmentResolved — whether the requested location/property-type combination actually matched something upstream.

ERROR — one row per input that failed

So every entry in Locations maps to at least one output row.

Input

FieldWhat it does
Locationsplace slugs as they appear in Zoopla's own URLs (london, manchester, rye) — one search per entry
For sale or to rentapplies to every location in the run
Property typeall types, houses, flats, bungalows or retirement homes — each verified live to genuinely narrow the result count
Min/max price, min/max bedroomsall four verified live as real filters, not silently ignored
Fetch listing detail pagesadds floor area/tenure/EPC/stations/price history (off by default — one extra request per listing)
Max properties / max pages per searchpagination caps — Zoopla pages honestly and caps itself at ~1,000 listings/query regardless
Max concurrent requests / Min seconds between requeststuned for the Cloudflare challenge described above — lowering these will not remove the occasional retry, it will just make the run slower

Example

{
"locations": ["london", "manchester"],
"section": "for-sale",
"propertyType": "houses",
"priceMax": 500000,
"includePropertyDetails": true,
"maxItems": 100
}

Notes on reliability

  • Filters are genuinely honest, a rare case in this portfolio's REAL_ESTATE family: an unrecognised location OR an unrecognised property-type path segment both answer a clean Next.js "not found" page (segmentResolved: false, zero rows) — Zoopla does not silently widen to a national/parent baseline the way most other targets here do.
  • Pagination is genuinely honest: ?pn=N really advances (verified: 0 listing-id overlap between consecutive pages), and a page past the real ceiling (pageNumberMax, ~40 pages/query) answers a clean HTTP 404 — no clamp-back-to-page-1 trap like several other actors in this portfolio have to work around.
  • totalResults is a real structured field (not scraped from page copy), but Zoopla itself caps the displayed figure at 50,000 and flags this via totalResultsWasLimited: true — the true count can be higher.
  • A dead/renamed detail listing answers HTTP 200 with a "not found" page shell, not a 404 — propertyDetail is simply null for that row rather than treated as a run failure.
  • An invalid section/propertyType from the API/CLI (bypassing the Console's enum picker) is refused up front with a clear ERROR row — never silently substituted with the default.

Output envelope

Every record carries _input, _source and _scrapedAt. Upstream field names pass through verbatim under listing (and propertyDetail when requested) — no renaming.

See CRAWLING_METHOD.md for the full reverse-engineering trail, including the Cloudflare TLS-profile ladder, the RSC flight-stream parsing approach, and the property types/filters that were probed but NOT verified (so are deliberately not offered).