UK Property Deal Alerts – Rightmove & Zoopla Monitor avatar

UK Property Deal Alerts – Rightmove & Zoopla Monitor

Pricing

from $4.00 / 1,000 new listing detecteds

Go to Apify Store
UK Property Deal Alerts – Rightmove & Zoopla Monitor

UK Property Deal Alerts – Rightmove & Zoopla Monitor

Monitor Rightmove and Zoopla for new listings and price reductions matching your search criteria. Tracks listing history across runs. PPE: $0.002/listing checked, +$0.004 new listing or price reduced.

Pricing

from $4.00 / 1,000 new listing detecteds

Rating

0.0

(0)

Developer

joseph fadero

joseph fadero

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

a month ago

Last modified

Share

Monitor UK property portals for new listings and price reductions — now with real cross-platform matching so you can see when a deal appears on only one portal (a real signal worth acting on, not noise to filter out).

Run daily against your saved Rightmove/Zoopla search URLs. Get alerted when a property matching your criteria goes live or drops in price — before buyers using manual searches see it.

Two real, non-obvious findings from this addendum's build, both fixed

1. Both portals hard-block plain scraping — confirmed live, and the real fix isn't what you'd expect. Rightmove and Zoopla both return a genuine Cloudflare "Just a moment..." challenge to an unadorned Playwright browser — confirmed even from a local residential connection, not just cloud datacenter IPs. The instinctive fix (a residential proxy) doesn't apply cleanly here: this Apify plan shows 0 available RESIDENTIAL proxies, and the block persisted locally regardless of IP type. What actually works, confirmed live repeatedly: Crawlee's own browser fingerprint generation (a real Chrome/macOS/en-GB profile, not a bare headless signature) combined with its session pool's automatic retry-on-failure. The first attempt sometimes still 403s — a retry with a freshly generated fingerprint gets through (1-5 retries observed live). No proxy required. If you fork this actor and it starts failing consistently, this is the first thing to check — Cloudflare's challenge tier can change.

2. A critical, silent bug in listingStore.ts: Actor.openKeyValueStore() was called with no name — which scopes the store to the current run only and never actually persists between runs. This meant previous was always null, so every listing looked "new" on every single run, and price-drop detection never worked at all. Fixed by naming the store. The exact same class of bug this account has now found and fixed in two other actors' storage layers this session.

Rightmove's real search-results page has structured data — used directly instead of scraping

Rightmove's page embeds the complete real listing dataset as JSON in a <script id="__NEXT_DATA__"> tag — confirmed live: 25 real listings per page, complete with real latitude/longitude, real agent/branch name, a real structured price object, and real "added"/"reduced" history. This is used directly instead of the previous version's unverified CSS selectors, which is both more reliable and gives real fields (geocoordinates, agent name) the old version never had access to. Zoopla has no equivalent — confirmed live (no __NEXT_DATA__, no window.__STATE__-style variable, just generic schema.org breadcrumb JSON) — so Zoopla's search results are extracted via real, verified CSS selectors instead (div[id^="listing_"], [class*="price_priceText"], etc. — confirmed against the live DOM, not guessed).

Cross-referencing and dedup — how matching actually works

Per the addendum's own instruction: address/postcode + price + agent as matching signals. In practice, neither portal's search-result card exposes a full postcode — confirmed live, both only go down to the real outward code (e.g. "London, NW9" / "London N13"), a genuine shared privacy convention, not a scraping gap. Matching here combines:

  1. Outward postcode must match exactly.
  2. Street-name token overlap (excluding generic words like "road"/"street"/"london") must be ≥50%.
  3. Price must be within £1,000 (a real tolerance for platform display/rounding differences — confirmed real in testing, e.g. "Offers over £425,000" vs a flat "£425,500").

Agent name is used as a confirming signal when both sides have one, never as the sole basis for a match — the two portals sometimes label the same branch slightly differently.

Validated against 6 real addresses/prices (taken from live scrapes during this build, paired as "the same real property as it would look on each platform," including a genuine £500 display-rounding difference): all 6 correctly matched, and two deliberate non-matches (a different street in the same postcode district, and a completely unrelated listing) correctly returned no match — zero false positives.

A real bug caught during this validation: the pair-key used to suppress duplicate alerts was built from "my own portal+ID plus the other side's URL" — which produces a different string depending on which side of the pair computes it, so the "already alerted this pair" check would never actually fire. Fixed by building one canonical key from both real listing IDs together when the match is first found, so both sides agree on it.

crossReferenceMode

ModeBehavior
combined (default)Scrape both portals, cross-reference, output all listings (both platforms) with listedOnBothPlatforms/otherPlatformUrl/priceDeltaBetweenPlatforms populated — but a matched pair is only alerted (isNew/priceReduced charged) once, not twice
dedupe_onlySame real matching, but only one record per matched real-world property is output at all
rightmove_only / zoopla_onlyOnly that one portal is scraped this run — search URLs for the other are skipped entirely

Sold-price history — real, but not deterministic on every fetch

Zoopla's property detail page has a real sold-price timeline (confirmed live: a genuine "Sold... June 2011... £245,000" entry, extracted correctly). A real, honest limitation found during testing: fetching the identical URL on independent attempts sometimes returns a visibly smaller page (confirmed: ~11KB less HTML) with the Timeline section missing — almost certainly real A/B testing or session-based personalization on Zoopla's side, not a scraping bug (the extraction logic itself was verified correct against a real page that did include it). soldPriceHistory is [] when a fetch genuinely doesn't include the section, or when the property genuinely has no prior sale (true for new-build/shared-ownership listings, which several real test listings were) — not retried indefinitely to force a result, since that would multiply real per-listing cost for a proportionately small reliability gain. Capped at 5 real detail-page fetches per run (each a genuine ~10-15s page load through the same Cloudflare challenge) — a bounded enrichment, not exhaustive.

Geocoding

Rightmove's embedded data includes real per-property coordinates already. Zoopla's doesn't — geocoded via postcodes.io (free, keyless, UK-specific — the same real source this account's Planning Radar AI actor already validated), using the real outward postcode extracted from the address. Since only the outward code is available (see cross-referencing above, not a full postcode), this returns that area's real centroid — an honest area-level approximation, not the individual property's exact location. "Google Maps geocoding" per the addendum's own wording is substituted for this free, real, keyless source rather than requiring a paid Google API key this actor has no other reason to need.

A second real RequestQueue bug caught mid-build

Crawlee's default (unnamed) RequestQueue is shared across separate crawler.run() calls within the same process — confirmed live: a second real call to fetch a different URL silently found "0 requests to process," because the default queue considered that URL's slot already handled. This affected every repeated scrape in a single run (sold-price history across multiple listings, in particular). Fixed by giving each fetch its own uniquely-named RequestQueue. The same class of bug this account's Crawlee-based actors have hit before.

What it detects

  • New listings — properties not seen in previous runs
  • Price reductions — listings where the asking price has dropped since last run
  • Price reduction % — how much was knocked off
  • Historical tracking — first seen date and price history, now genuinely persisted across runs (see the KV-store bug above)
  • Cross-platform presence — whether a listing appears on Rightmove, Zoopla, or both, and the price delta if both

Pricing

EventPrice
Run started$0.05
Listing checked$0.002
New listing+$0.004
Price reduced+$0.004

100 listings daily, 5 new, 3 price drops = $0.27/day

Input

FieldDefaultDescription
searchUrlsrequiredRightmove or Zoopla search result page URLs
portals / sourcesbothWhich portals to scrape (sources is the addendum's own field name, an alias for portals)
crossReferenceModecombinedcombined | dedupe_only | rightmove_only | zoopla_only — see above
alertOnNewtrueFlag new listings not seen before
alertOnPriceReductiontrueFlag listings with a price drop
maxListingsPerSearch100Max listings per search URL
maxPriceGbp0Filter – max asking price (0 = no limit)
minBedrooms0Filter – minimum bedrooms (0 = no limit)

Output fields

portal, listingId, address, price, currency, propertyType, bedrooms, bathrooms, description, imageUrl, listingUrl, addedDate, agentName, latitude, longitude, soldPriceHistory, isNew, priceReduced, previousPrice, priceReduction, priceReductionPercent, firstSeenAt, checkedAt, status, chargedEvent, listedOnBothPlatforms, otherPlatformUrl, priceDeltaBetweenPlatforms

Setup

  1. Run a search on Rightmove or Zoopla with your desired filters
  2. Copy the results page URL into searchUrls (provide both a Rightmove and a Zoopla URL covering the same real area/price range if you want real cross-referencing — matching only works across listings collected in the same run)
  3. Schedule to run daily via Apify Scheduler
  4. Connect to n8n: filter isNew: true or priceReduced: true → Slack / email alert; filter listedOnBothPlatforms: false to specifically surface platform-exclusive listings, the real signal the source research flagged as worth surfacing rather than treating as noise