SPB Git

spb/lou-ka Public

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

HTML 99.7%
4.5 KB

# louis14 — Quartier Louis Quatorze (louis14.ca)

  • site: https://louis14.ca/plans/ (Groupe Damco — 423 condos locatifs, immeubles Quartier A-B et C-D, 1010 rue des Gadelles, Lebourgneuf, Québec ; phase E-F à venir, 0 unité saisie)
  • méthode: html + flux RSC Next.js — la page /plans/ embarque le sélecteur de plans Livya (app.livya.com, ex-RealVuu) ; sa page est rendue serveur et son payload self.__next_f.push contient les 423 unités complètes (2 requêtes au total, aucun rendu JS)
  • annonces: 18 (unités AVAILABLE seulement, sur 423 ; uid = numéro d'unité « 816-C », stable et unique)
  • couverture (sur 18 annonces): prix 100% (réels, 1 951–2 850 $), type 100% (3½/4½/5½ depuis rooms), superficie 100% (pi², structurée), disponibilité 100% (dont 2 dates futures structurées 2026-09-01), adresse 100% (rue + ville + code postal), GPS 100%, étage/orientation/balcon 100% (details), photos 100% (photo du type + plan d'étage)
  • fixture: ok (2 requêtes) · test: ok (2 verts)

# Découverte technique (anti-bot / prix cachés)

  • louis14.ca renvoie 403 sans UA navigateur ; le UA de base.py passe (Cloudflare + email-protection/rocket-loader actifs mais sans challenge).
  • Les prix ne sont nulle part dans le WordPress (pas d'admin-ajax ni wp-json de disponibilités ; admin-ajax.php ne sert que les plugins). La vraie source est le widget Livya de /plans/ : <div class="livya-module-container-plans" data-project="louis-14" data-entity="e5e643c4-…"> + <script src="https://app.livya.com/embed.js" data-client="damco">.
  • embed.js construit l'iframe https://app.livya.com/fr/{client}/projects/{project}/plans/{entity} — cette page Next.js est rendue serveur : le flux RSC embarqué contient projet, immeubles, étages et les 423 objets unité complets (unitId, number, availability, rentalPrice, rooms, unitSize, floorNumber, orientation, balconySize, typeImages, floorPlanImageUrl, lat/lng, adresse…). L'API sous-jacente (api.realvuu.com/app) n'est pas devinable (404), mais inutile.
  • Décodage : chaque fragment self.__next_f.push([1,"…"]) est un corps de chaîne JSON → json.loads('"'+fragment+'"') puis recollage ; les objets {"unitId":…} sont extraits par JSONDecoder.raw_decode (même approche que le connecteur interrent).

# Champs extraits

  • prix : rentalPrice par unité (réel, jamais affiché sur le WordPress)
  • disponibilité : availability (AVAILABLE/NOT_AVAILABLE) + futureAvailability.startsOn ISO → availability_date structurée (« Disponible à partir du 2026-09-01 »)
  • type : rooms (3.5/4.5/5.5) → 3½/4½/5½ ; roomsBed/roomsBath → details.bedrooms/bathrooms
  • superficie : unitSize en pi² (measurementSystem=IMPERIAL vérifié avant de promouvoir)
  • adresse/GPS : portés par chaque unité (1010 Rue des Gadelles, Québec, G2J 1T8 ; 46.8476, -71.2924)
  • immeuble : mapping buildingId → nom (« QUARTIER A-B », « QUARTIER C-D ») dans le titre
  • étage (floorNumber/floorDisplayName, incl. « RDC »), orientation, balcon (pi²) → details + items d'affichage dans amenities
  • photos : typeImages.fullUrl (photo du type d'unité) + floorPlanImageUrl (plan), URLs CloudFront absolues

# Champs indisponibles à la source

  • description, attributes, unitTags, clienteles, minLeaseDurationMonths, electricityCoverage : présents dans le schéma Livya mais vides pour ce projet (aucune inclusion/commodité saisie)
  • animaux : seul dogsAllowed=false existe au niveau des étages de la phase E-F (vide) — pas exploitable
  • secteur : district null au flux (Lebourgneuf n'apparaît que dans le SEO du site) — laissé vide
  • pages détail par unité : inexistantes ; url = /plans/ pour toutes les annonces

# Fragilités

  • Dépend du format RSC de Next.js côté Livya (self.__next_f.push) : un changement de framework casserait le parsing (couvert par la fixture, précédent : connecteur interrent)
  • data-entity (id du sélecteur de plan) lu dynamiquement sur /plans/, repli constant — si Damco recrée le module, le repli devient obsolète mais l'extraction dynamique suit
  • Le site parle de 4 immeubles A-B-C-D : Livya les regroupe en 2 bâtiments (A-B et C-D, 213 + 210 unités = 423, pas 424) ; la lettre du numéro d'unité (« 816-C ») porte l'immeuble réel
  • availability="Disponible" est un libellé composé depuis l'énum source AVAILABLE (le flux est un enum, pas un texte)
  • Si aucune unité n'est AVAILABLE à une sync, le connecteur retourne 0 annonce (comportement voulu : on n'annonce que du réel)