# ----------------------------------------------------------------------------- # Lou-Ka — Agrégateur de logements à louer (province de Québec) # Auteur : Simon-Pierre Boucher — contact@spboucher.ai # connectors/le_st_georges.py : connecteur Le St-Georges (lestgeorges.ca) # 11 295, 1re Avenue, Saint-Georges (Beauce, Chaudière-Appalaches) — # 56 unités locatives sur 7 étages habités (3½ à 5½). # Même plateforme WordPress « do-selecteur-plans » que La Cour Appartements # et AULA Lévis : sélecteur SVG d'unités (polygones data-nom / data-etage / # data-type / data-prix, classes disponible / indisponible « Loué ») + REST # /wp-json/do-selecteur-plans/v1/unite (montant, superficies habitable et # balcon, plan PDF, libellé « Libre le … »). Tout le parsing et le cache BD # sont hérités de LaCourConnector ; seules changent les constantes du projet # et deux particularités du thème : # - le sélecteur est sur la PAGE D'ACCUEIL (PLANS_PATH vide) ; # - les photos du projet sont des PNG (le motif partagé ne retient que # jpg/webp) et les commodités sont des blocs `.sc_icons_item_title` # -> _site_images() et _project_amenities() sont redéfinies. # Les unités louées sont exclues (classe « indisponible », état REST). # ----------------------------------------------------------------------------- from __future__ import annotations import re from bs4 import BeautifulSoup from .la_cour import LaCourConnector _IMG_RE = re.compile( r'https?://[^"\'\s\)]+/wp-content/uploads/[^"\'\s\)]+' r'\.(?:jpg|jpeg|png|webp)', re.I) _SKIP_IMG = re.compile( r"logo|\blog[_-]|icon|favicon|badge|plan|selecteur" r"|-\d{2,4}x\d{2,4}\.", re.I) class LeStGeorgesConnector(LaCourConnector): source_id = "le_st_georges" BASE = "https://lestgeorges.ca" PLANS_PATH = "" # le sélecteur d'unités est sur l'accueil NAME = "Le St-Georges" ADDRESS = "11 295, 1re Avenue, Saint-Georges, QC G5Y 2C2" SECTOR = "Centre-ville" CITY = "Saint-Georges" PHOTO_PAGES = ("",) # photos publiées sur l'accueil AMENITY_PAGES = ("",) # -- particularités du thème ----------------------------------------------- def _site_images(self) -> list[str]: """Photos du projet : uploads jpg/png/webp de l'accueil (le thème publie des PNG), hors logos, badges et plans d'unités.""" imgs: list[str] = [] for page in self.PHOTO_PAGES: try: html = self.get(f"{self.BASE}/{page}").text except Exception: continue for u in dict.fromkeys(_IMG_RE.findall(html)): if not _SKIP_IMG.search(u) and u not in imgs: imgs.append(u) return imgs[: self.max_images] def _project_amenities(self) -> list[str]: """Commodités de l'immeuble : titres des blocs « Nos espaces, votre confort » (`.sc_icons_item_title`) de l'accueil.""" items: list[str] = [] for page in self.AMENITY_PAGES: try: html = self.get(f"{self.BASE}/{page}").text except Exception: continue soup = BeautifulSoup(html, "html.parser") for el in soup.select(".sc_icons_item_title"): t = re.sub(r"\s+", " ", el.get_text(" ", strip=True)).strip() if 3 <= len(t) <= 90 and t not in items: items.append(t) return items[:30]