spb/lou-ka Public
Lou·Ka — tous les logements à louer du Québec, un seul endroit.
HTML 99.7%
1# -----------------------------------------------------------------------------2# Lou-Ka — Agrégateur de logements à louer (province de Québec)3# Auteur : Simon-Pierre Boucher — contact@spboucher.ai4# connectors/gestimmo_estrie.py : connecteur Gestimmo Estrie (gestimmoestrie.com)5# Gestionnaire multi-immeubles de Sherbrooke et de l'Estrie. Même plateforme6# WordPress + thème Houzez que Gestion Dynamic : tout le parsing (cartes,7# pagination /a-louer/page/N/, fiches détail, cache BD) est hérité de8# DynamicConnector. Particularités du site :9# - la disponibilité est l'étiquette de statut de la carte10# (lien /status/ : « Libre maintenant », « Juillet », « Loué »…) ;11# - les fiches n'ont pas d'aperçu Houzez : le type d'unité vient du titre12# (« 4 1/2 Rue de la Sainte-Famille ») ou de la ligne « Grandeur : 4 1/2 »13# de la description.14# Les logements « Loué » sont exclus (filtre hérité).15# -----------------------------------------------------------------------------16from __future__ import annotations1718import re1920from .dynamic import DynamicConnector2122# « Grandeur : 4 1/2 » / « Grandeur: Studio » dans la description des fiches23_SIZE_IN_DESC = re.compile(r"grandeur\s*:?\s*(\d\s*1/2|\d\s*½|studio|loft)", re.I)242526class GestimmoEstrieConnector(DynamicConnector):27 source_id = "gestimmo_estrie"2829 BASE = "https://gestimmoestrie.com"30 LIST_PATH = "/a-louer/"31 CITY_DEFAULT = "Sherbrooke"3233 # -- crochets par site --------------------------------------------------------34 def _card_availability(self, card, title: str) -> str:35 """Gestimmo : étiquette de statut de la carte (« Libre maintenant »,36 « Juillet », « Loué »…)."""37 status_el = card.select_one("a[href*='/status/']")38 return status_el.get_text(" ", strip=True) if status_el else ""3940 def _fetch_detail(self, url: str) -> dict:41 """Fiche Houzez sans bloc aperçu : repli type d'unité sur la ligne42 « Grandeur : … » de la description."""43 out = super()._fetch_detail(url)44 if not out.get("type_raw") and out.get("description"):45 m = _SIZE_IN_DESC.search(out["description"])46 if m:47 out["type_raw"] = m.group(1)48 return out49