Skip to content

Kangalou Scraper — Technical Analysis

Platform Overview

Kangalou is Quebec's #1 rental listings platform, owned by CORPIQ (Corporation des propriétaires immobiliers du Québec, 30,000 landlord members). Free for landlords to post, with paid visibility packages ($40-$540).

  • ~7,500 active listings (mostly Montreal)
  • ~1M+ monthly page views
  • Bilingual (FR/EN)
  • URL: https://kangalou.com

Data Available Per Listing

FieldAvailableNotes
TitleYesProperty type + size + location
Price (rent/month)YesIn dollars
Property typeYesApartment, condo, house, room, loft, studio
Size (rooms)YesQuebec notation: 3½, 4½, 5½
Bedrooms / BathroomsYesNumeric
FloorYesFloor number
Area (sq ft / m²)YesBoth units
Availability dateYesSpecific date or "now"
City / NeighborhoodYesMontreal neighborhoods
DescriptionYesFull text, mostly French
ImagesYesMultiple, via kangalou.com/images/glide/
Coordinates (lat/lng)YesEmbedded in HTML — no geocoding needed
Street addressPartialSome in URL slug, some neighborhood only
AmenitiesYesPets, parking, laundry, furnished, etc.
Contact nameYesLandlord name on page
Phone numberAuth-gatedRequires login + reCAPTCHA v3
EmailNoMessage form only
Listing IDYesNumeric (e.g., 222455)

Technical Architecture

ComponentDetails
ServerNginx (no CDN, no Cloudflare)
BackendPHP (custom, not WordPress/Laravel)
FrontendjQuery, server-side rendered HTML
MapsGoogle Maps
Anti-botNone — no WAF, no CAPTCHA on search, no rate limiting

Internal API Endpoints

Discovered from JS bundle at /dist/js/kangalou.js:

EndpointMethodAuthPurpose
/:lang/api/searchPOSTNoMain search — returns JSON with HTML listings
/:lang/api/processPOSTNoAutocomplete/instant search
/:lang/api/listings/:id/contact-phoneGETYes (401)Phone number reveal
/:lang/api/listings/:id/contact-messagePOSTYesSend message
/:lang/api/listings/:id/visit-daysGET?Visit schedule
/:lang/api/postal-codes/:code/locationsGETNoPostal code lookup

Search API

POST /:lang/api/search — the main discovery endpoint.

Parameters (form body):

  • search-string — text query (e.g., "montreal")
  • search-filter-city — city filter
  • search-filter-sort — sort order (newest, pasc)
  • page — pagination (1-indexed)
  • s — size filter
  • t[] — type filter (array)
  • pmin / pmax — price range
  • f[] — feature/amenity filter
  • g[], z[] — unknown filters

Response: JSON { ok: true, html: "<div>...</div>" } — server-rendered HTML with listing cards.

~53 listings per page, ~142 pages for full inventory.

URL Structure

  • Search: /:lang/search/ or /:lang/recherche/
  • City: /:lang/location/:city/
  • Neighborhood: /:lang/location/:city/:neighborhood/
  • Detail: /:lang/listing/:slug/:id/ (EN) or /:lang/annonce/:slug/:id/ (FR)

Anti-Bot Assessment

MeasureStatus
Cloudflare / WAFNone
CAPTCHA on searchNone
CAPTCHA on phonereCAPTCHA v3 (site key: 6LepJboUAAAAAIWJCyG8PzlT2kTSl6fGmVtRSZXi)
Rate limitingNone detected
Bot detection JSNone
User-Agent checkNone — curl works
IP blockingNot observed

Verdict: Very low protection. Orders of magnitude easier than Kijiji.

HTTP-only — no Playwright/browser needed.

  1. Discovery: POST to /en/api/search with pagination → listing URLs + basic card data
  2. Detail: GET each listing page → full data (description, coordinates, amenities, images, contact name)
  3. Phone numbers: Skip unless account is created (auth + reCAPTCHA v3)

Stack: undici/fetch + cheerio for HTML parsing. Fits existing BaseScraper interface.

Estimated Scrape Time

PhaseVolumeTime (sequential)Time (5 concurrent)
Search pages142 pages × 18s~43 min~9 min
Detail pages7,500 × 3.6s~7.5 hours~1.5 hours
Total~2 hours

Phone Numbers

Phone numbers are behind auth at /:lang/api/listings/:id/contact-phone (returns 401 without login). Also protected by reCAPTCHA v3.

Options:

  1. Create an account, solve reCAPTCHA v3 tokens programmatically — moderate difficulty
  2. Skip phone numbers initially, only import listings with phones from other sources
  3. Use Playwright for phone reveal (same approach as Kijiji) — heavier but proven

Moderate — same category as Kijiji.

ToS prohibitions:

  • "use, download or otherwise copy... any directory of Users"
  • "gather or otherwise collect information about others, including email addresses"
  • All content copyrighted by Kangalou/CORPIQ

Mitigating factors:

  • Listing data is publicly accessible without login
  • No aggressive anti-bot enforcement suggests they tolerate some scraping
  • Phone numbers are the most sensitive data (auth-gated)

Risk owner: CORPIQ — organized Quebec landlord association with resources to enforce.

Mitigation: Avoid storing landlord names. Rate-limit respectfully. Don't scrape phone numbers without careful consideration.

Comparison to Kijiji

FactorKijijiKangalou
Anti-botHigh (Cloudflare, reCAPTCHA Enterprise)Very low (nothing)
Browser neededYes (Playwright)No (HTTP + cheerio)
Data formatApollo GraphQL JSONServer-rendered HTML
Phone numbersreCAPTCHA Enterprise (hard)Auth + reCAPTCHA v3 (moderate)
Listings (MTL)~5,000-10,000~7,500
Rate limitingAggressiveNone
Implementation effort2-3 weeks3-5 days
Overlap with KijijiN/ALow-moderate
Coordinates includedNo (need geocoding)Yes (embedded)

Implementation Priority

High priority — easiest scraper to build. Kangalou should be the next scraper after Kijiji because:

  1. Zero anti-bot → simple HTTP client
  2. No browser dependency → faster, less resource-intensive
  3. Coordinates embedded → no geocoding API calls needed
  4. Good data quality (CORPIQ-verified landlords)
  5. Complementary inventory to Kijiji
  6. 3-5 day implementation estimate