Skip to content
# 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).
- 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)