🏠 Rental Listings Scraper β€” Canada, UK & USA | Geo Enriched avatar

🏠 Rental Listings Scraper β€” Canada, UK & USA | Geo Enriched

Pricing

from $2.00 / 1,000 listings

Go to Apify Store
🏠 Rental Listings Scraper β€” Canada, UK & USA | Geo Enriched

🏠 Rental Listings Scraper β€” Canada, UK & USA | Geo Enriched

Apartments, houses, flats & rooms for rent from Kijiji + RentFaster (Canada), OpenRent (UK) and Zumper (USA) in one normalized schema: price, beds, coordinates, currency. Filters: max rent, bedrooms, keywords, near an address or subway/grocery/school. Cross-source dedup + map. Agent/MCP-ready.

Pricing

from $2.00 / 1,000 listings

Rating

0.0

(0)

Developer

Soroosh Esmaeilian

Soroosh Esmaeilian

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

3

Monthly active users

7 days ago

Last modified

Share

Rental Listings Scraper β€” Canada πŸ‡¨πŸ‡¦ + UK πŸ‡¬πŸ‡§ + US πŸ‡ΊπŸ‡Έ + Geo Data 🏠

One normalized, deduplicated feed of rental listings β€” Kijiji and RentFaster.ca for Canada, OpenRent for the UK, Zumper for the US β€” with optional nearest-amenity distances (transit, grocery, school, …) attached to every listing.

Most rental scrapers give you one site in that site's own ad-hoc shape. This Actor gives you every source in a single schema across countries, collapses the same unit posted to multiple sites into one row, and can tell you how far each place is from the subway β€” a signal no other rental scraper on Apify ships.

Why this is different

Typical single-site scraperThis Actor
SourcesOneKijiji + RentFaster (CA), OpenRent (UK), Zumper (US)
SchemaPer-site, ad-hocOne unified schema across sources & countries
DuplicatesYou dedupe yourselfCross-source dedup built in (also_on)
Location intelligenceLat/lng onlyNearest-amenity distances, included free

Input

Scope

FieldTypeDefaultNotes
countrystring"CA"CA (Kijiji + RentFaster), GB (OpenRent), or US (Zumper)
sourcesarrayall for the countrySites to scrape; other countries' sources are ignored
citiesarray[] (all)City names, e.g. ["Toronto","Calgary"], ["London"], ["Austin","Seattle"]
maxPerCityint100Cap per city, per source
dedupebooltrueMerge cross-source duplicates

Filters (all optional β€” applied cheapest-first)

FieldTypeNotes
minRent / maxRentintMonthly rent bounds, e.g. maxRent: 2500
minBedrooms / maxBedroomsintFor exactly 2-bed, set both to 2. 0 = include bachelor
keywordsarrayTitle/description must contain ALL (case-insensitive). e.g. ["female"], ["parking","balcony"]
excludeKeywordsarrayDrop if title/description contains ANY. e.g. ["no pets"]
nearAmenitiesarrayKeep listings within maxAmenityDistanceM of each type: subway, train, bus_stop, grocery, cafe, pharmacy, park, school, university, library, gym, hospital. Auto-enables enrichment
maxAmenityDistanceMintDefault 800 (β‰ˆ10-min walk)
nearAddressstringA specific place to anchor on, e.g. "200 Bay St, Toronto". Geocoded, then listings kept within nearAddressRadiusM. Use this for "near my workplace"
nearAddressRadiusMintDefault 2000

Enrichment & infra

FieldTypeDefaultNotes
enrichAmenitiesboolfalseAttach amenity_distances_m even without a nearAmenities filter (fast, free)
enrichRadiusMint1500Amenity search radius
maxEnrichint200Cap on listings enriched per run
proxyConfigurationobjectApify Proxy onRecommended β€” see below

Examples:

// minimal
{ "sources": ["kijiji", "rentfaster"], "cities": ["Toronto"], "maxPerCity": 50 }
// "2-bed under $2500 in Toronto, near a subway, female-only"
{
"cities": ["Toronto"], "minBedrooms": 2, "maxBedrooms": 2,
"maxRent": 2500, "nearAmenities": ["subway"], "maxAmenityDistanceM": 800,
"keywords": ["female"]
}
// "1-bed within 2 km of my office at 200 Bay St"
{ "cities": ["Toronto"], "maxBedrooms": 1, "nearAddress": "200 Bay St, Toronto", "nearAddressRadiusM": 2000 }

"Near X" β€” two different mechanisms

  • Near a type of place (subway, grocery, university…) β†’ nearAmenities. Backed by OpenStreetMap; great coverage in Canadian cities.
  • Near a specific place (your office, a named landmark) β†’ nearAddress. Geocoded to one point. Amenity categories can't find a specific employer (OSM may not have "Company X"), so use nearAddress for that.

Description questions (e.g. "female only", "no pets")

The full description is always in the output. For literal phrases, use keywords / excludeKeywords (deterministic, server-side). For nuanced interpretation, let an LLM read the returned descriptions β€” e.g. via Apify's MCP server, Claude can run this Actor and reason over the results in chat. Note: keyword matching is literal, so it depends on how the lister phrased it, and gender-restricted whole-unit ads may run into provincial human-rights rules (shared/roommate situations are typically exempt) β€” that's on the data, not the filter.

Output

Each dataset item (empty fields omitted):

{
"source": "kijiji",
"also_on": ["rentfaster"],
"source_id": "1700123456",
"url": "https://www.kijiji.ca/v-apartments-condos/...",
"title": "Bright 2BR near subway",
"address": "123 King St W, Toronto, ON",
"city": "Toronto",
"province": "ON",
"postal_code": "M5V 1J5",
"lat": 43.6453,
"lng": -79.3806,
"country": "CA",
"monthly_rent": 2450,
"currency": "CAD",
"bedrooms": 2.0,
"bathrooms": 1.0,
"sqft": 720,
"property_type": "apartment",
"furnished": false,
"pet_friendly": true,
"utilities_included": ["heat", "water"],
"available_from": "2026-07-01",
"description": "…",
"amenity_distances_m": { "subway": 320, "grocery": 150, "park": 410 },
"scraped_at": "2026-06-27T12:00:00+00:00"
}

bedrooms: 0.5 means bachelor/studio. also_on lists other sites the same unit was found on (only when dedupe is enabled). monthly_rent is always a per-calendar-month figure in currency (CAD or GBP) β€” weekly UK quotes are normalized for you.

UK specifics (country: "GB", OpenRent): province holds the nation code (ENG/SCT/WLS/NIR), postal_code is the outward code only ("WC2N" β€” UK listings don't publish full postcodes before enquiry), and description is the search snippet, not the full ad text.

US specifics (country: "US", Zumper): province holds the state code, apartment complexes yield one row per advertised floorplan (same address, distinct source_id), monthly_rent is that floorplan's "from" price, and description is a short summary.

Use it from Claude (MCP) πŸ€–

This Actor is built to be driven by an AI agent, not just a form. Connect Apify's MCP server to Claude (Desktop, Claude Code, or any MCP client) and Claude can run it from a plain-English request, then reason over the results β€” no code.

  1. Add the hosted MCP server https://mcp.apify.com (OAuth), or run @apify/actors-mcp-server locally with your APIFY_TOKEN.
  2. In Claude, just ask:

    "Run the Canada rentals actor for Toronto β€” 2-bed under $2500 near a subway β€” and recommend the best 3."

Claude maps that straight onto the inputs β€” {cities:["Toronto"], minBedrooms:2, maxBedrooms:2, maxRent:2500, nearAmenities:["subway"]} β€” runs the Actor, reads the dataset, and answers in chat. Because the filters (maxRent, minBedrooms, keywords, nearAmenities, nearAddress) are pushed into the Actor, Claude isn't post-filtering a huge blob β€” it gets a short, correct set back. The amenity_distances_m field is what lets it answer "near a subway / grocery / school" precisely instead of guessing from text.

Proxy β€” please read

  • RentFaster.ca, OpenRent, and Zumper sit behind bot challenges that fingerprint the TLS handshake, so browser-like headers alone get blocked. The Actor forges a real Chrome TLS/HTTP2 fingerprint (via curl_cffi) on a sticky IP to clear them; a residential proxy is still recommended for a clean IP.
  • Kijiji rate-limits and blocks datacenter IPs aggressively.

Use Apify Proxy (residential group) for production runs, and set apifyProxyCountry to match your country input (CA, GB, or US). The default input already enables Apify Proxy.

Amenity enrichment

Nearest-amenity distances come from bundled offline POI indexes β€” ~225k Canadian, ~529k UK, and ~1.14M US POIs (OpenStreetMap, via Geofabrik) shipped inside the Actor and queried in-process. No external API, no rate limits: enriching hundreds of listings takes well under a second, and it's included free (no per-listing enrichment charge). Stations, groceries, cafes, pharmacies, schools, universities, libraries, gyms and hospitals carry their OSM name too β€” the map labels them "Charing Cross β€” subway Β· 240m", not just a dot. The snapshots are refreshed periodically; POIs are static infrastructure so they don't need to be live.

Scrapes only publicly visible listing data β€” no logins, no private data. You are responsible for your use of the output. Kijiji and RentFaster each have Terms of Use that restrict automated access; review them and your jurisdiction's rules, run politely (low concurrency, sensible caps), and don't redistribute in ways those terms prohibit. This Actor is provided for research and personal use.

Roadmap

  • Australia. Every major AU portal (Domain, realestate.com.au, Gumtree AU, Flatmates, rent.com.au) hard-blocks automation today; support waits on a headless-browser approach being worth it.
  • More UK/US sources for cross-source dedup (OpenRent and Zumper are single-source per country today).
  • Facebook Marketplace + rentals.ca sources (best-effort; both are anti-bot).
  • Listing-level change tracking (price drops, relistings).

Development

This repo is the Actor: src/ is the code that runs on Apify (python -m src), .actor/ holds the actor/input/dataset schemas, and the Dockerfile builds the image. src/data/pois_<cc>.npz are the bundled offline POI indexes, one per country (rebuild from Geofabrik extracts with tools/build_poi_index.py --country CA β€” needs pip install osmium β€” then push). Adding a source or country starts at the registry in src/sources/__init__.py.

python3.12 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python test_smoke.py # offline: parsing, dedup, filters (also runs in CI)
.venv/bin/python live_check.py # hits the real sites, no Apify SDK needed
.venv/bin/python harness_e2e.py # full pipeline against live sites, Apify calls stubbed
apify push # deploy (manual β€” no CI deploy)

Local live_check/harness_e2e runs may see Kijiji 403s from home/datacenter IPs β€” that means "use a residential proxy", not "the code is broken"; the real Kijiji test is a cloud run with Apify Proxy (residential group).

Before touching scrapers or dependency pins, read docs/PROJECT_NOTES.md β€” it records which sites are viable, the exact Cloudflare workarounds, and the load-bearing version pins.