# ----------------------------------------------------------------------------- # Lou-Ka — Agrégateur de logements à louer (province de Québec) # Auteur : Simon-Pierre Boucher — contact@spboucher.ai # connectors/logisco.py : connecteur Logisco (logisco.com) # Site rendu serveur. Crawl : page liste principale (+ pages villes) pour # découvrir les pages projets, puis extraction des unités disponibles # (cartes .unitCard) sur chaque page projet. Une annonce par unité. # Chaque page unité (mise en cache via self.detail, plafond 150 vraies # requêtes/sync) apporte : JSON-LD (adresse avec no d'unité + code postal, # étage, téléphone, plan de l'unité), superficie/étage/dispo structurés # (sommaire .unitHeader) et les 4 sections de commodités (Inclusions, # Particularités, Services offerts, Espaces communs). # Villes retenues : Québec, Lévis, Saint-Augustin-de-Desmaures # (Donnacona et autres villes hors région exclues). # ----------------------------------------------------------------------------- from __future__ import annotations import hashlib import html as htmllib import json import re from urllib.parse import urljoin from bs4 import BeautifulSoup from ..schema import Listing, infer_city, normalize_unit_type, parse_price from .base import BaseConnector BASE = "https://logisco.com" LIST_URL = f"{BASE}/fr/appartements-a-louer" # villes de la région Québec/Lévis retenues (segment d'URL -> nom de ville) CITY_MAP = { "quebec": "Québec", "levis": "Lévis", "saint-augustin-de-desmaures": "Saint-Augustin-de-Desmaures", } PROJECT_HREF_RE = re.compile( r'href="(https://logisco\.com/fr/appartements-a-louer/([a-z0-9\-]+(?:/[a-z0-9\-]+)*))"' ) STATIC_IMG_RE = re.compile( r'(?:src|data-src|href)="(https://logisco\.com/static/[^"]+\.(?:webp|jpe?g|png))"' ) EXCLUDE_UNIT_RE = re.compile(r"stationnement|parking|rangement|commercial|garage", re.I) def _text(el, sep: str = " ") -> str: """Texte d'un élément, robuste aux