SPB Git

spb/lou-ka Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

HTML 99.7%
4.5 KB

# centurion — Centurion / CP Living (cpliving.com)

  • site: https://www.cpliving.com/apartments-for-rent/quebec-city (Quartier QB, 2551 ch. des Quatre-Bourgeois, Sainte-Foy — 684 unités)
  • méthode: json-api — flux Rentsync/Lift https://api.theliftsystem.com/v2/search?client_ids=21&city_ids=2310 (paramètres et auth_token lus dynamiquement sur la page + scripts/main.js, replis constants) ; galerie photo de la fiche propriété derrière le cache BD self.detail()
  • annonces: 1 (une par propriété de la région de Québec ; uid = id Lift 79867, stable)
  • couverture (sur 1 annonce): adresse 100% (rue + ville + code postal), GPS 100%, description 100%, commodités 100%, photos 100% (6, pleine résolution), contact 100% ; prix/type/superficie/date : indisponibles tant que « No Vacancy » (voir plus bas)
  • fixture: ok (4 requêtes) · test: ok (2 verts)

# Découverte technique (anti-bot / Cloudflare)

  • La page de recherche référence un proxy legacy widgets/search/api_proxy.php?client_id=21&city_id=2310 (attribut data-ms-bcp du div .search-data) — il renvoie 404 aujourd'hui : c'est un vestige. Le JS réel (/scripts/main.js) appelle https://api.theliftsystem.com/v2/search avec un auth_token embarqué en clair (sswpREkUtyeYjeoahA2i pour le client 21 en production).
  • Cloudflare accepte le UA de base.py sur cpliving.com ET sur api.theliftsystem.com : aucun rendu JavaScript nécessaire (plan (a) du protocole — l'endpoint direct suffit, ni session préalable ni Firecrawl).
  • Subtilité du flux : city_ids (pluriel) + show_all_properties=true sont requis ; la requête « complète » du site (min_rate=0&max_rate=10000…) renvoie une liste vide quand la propriété n'a aucune unité disponible (rates null filtrés côté API).

# Champs extraits

  • Flux Lift : id, permalink, name, address{address, city, province_code, postal_code, neighbourhood}, geocode{latitude, longitude}, availability_status_label (« No Vacancy »), min_availability_date, statistics.suites{rates.min/max, bedrooms, bathrooms, square_feet} (remplis seulement quand il y a vacance → prix « À partir de X $ », type d'unité si gamme sans ambiguïté, superficie min), details.overview (description HTML → texte), promotion, custom_fields.amenities (CSV : « In-suite laundry, Dishwasher, Microwave, Air conditioner, Balcony »), contact.phone → details.contact, pet_friendly (true → pets=« oui » ; false ignoré : ne distingue pas « interdit » de « non renseigné »)
  • Fiche propriété (HTML rendu serveur) : galerie assets.rentsync.com, réécrite en /gallery/full/ (vérifié 200), via self.detail() (clé = hash de availability_count/status/rates/min_availability_date/photo → revisitée seulement quand le flux bouge)

# Champs indisponibles à la source

  • Prix, type d'unité, superficie, date de disponibilité : le Quartier QB est à « No Vacancy » (availability_count=0, statistics.suites tout à null) — l'annonce documente l'immeuble et se remplira automatiquement dès qu'une unité se libère
  • Détail par unité/suite : le site n'expose que /v2/search (aucun endpoint suites) ; le sommaire statistics.suites est le maximum disponible
  • Secteur : neighbourhood vide au flux (Sainte-Foy n'apparaît que dans la description) ; meublé, étage

# Fragilités

  • auth_token embarqué dans main.js : extrait dynamiquement (motif client_id=21",e="&auth_token=…"), repli constant — un changement de minification casserait l'extraction (couvert par le repli + la fixture)
  • REIT national (104 propriétés au flux sans filtre) : le garde-fou _QC_CITIES doit être maintenu si Centurion acquiert dans d'autres villes de la région
  • Libellés du flux en anglais (« No Vacancy ») — stockés bruts
  • Le format de min_availability_date (vide aujourd'hui) est supposé ISO ; seul un préfixe AAAA-MM-JJ strict est promu en availability_date

# Améliorations

  • 2026-08-08 — Expansion provinciale (lot 0) : city_ids=2310,1039 (Québec + Gatineau, id vérifié au recensement Outaouais) ; garde-fou province_code=QC conservé et _QC_CITIES étendu (gatineau/hull/aylmer). Le flux Gatineau accole la province au nom de ville (« Gatineau QC ») → suffixe retiré (_city_key + affichage). Correctif au passage : square_feet.min="0.0" publié par le flux Gatineau produisait area_sqft=0.0 (invalide) — garde de plausibilité 80–20 000 pi². +3 annonces à Gatineau : Nox (1 499 $), Nox 3 (1 525 $), Appartements Central (1 499 $), toutes « Available Now ». 1 → 4 annonces. Fixture réenregistrée (7 requêtes), 2 tests verts.