Lou·Ka — tous les logements à louer du Québec, un seul endroit.
HTML 98.9%
Python 0.6%
1# -----------------------------------------------------------------------------2# Lou-Ka — Agrégateur de logements à louer (province de Québec)3# Auteur : Simon-Pierre Boucher — contact@spboucher.ai4# connectors/beloeil_94.py : connecteur Le 94 Vieux-Beloeil (94beloeil.ca)5# Immeuble unique au 915, rue Guertin (Vieux-Beloeil) : commerce au RDC et6# 8 appartements 3½ (1 c.c.) au-dessus. Site vitrine statique (constructeur7# maison, rendu serveur) : une seule offre affichée sous forme de bandeau8# « 3 1/2 disponible <mois année> » + liste des inclusions. Granularité :9# typologie (une annonce 3½ quand l'immeuble affiche une disponibilité).10# -----------------------------------------------------------------------------11from __future__ import annotations1213import re1415from bs4 import BeautifulSoup1617from .base import BaseConnector18from ..schema import Listing1920BASE = "https://www.94beloeil.ca"2122ADDRESS = "915, rue Guertin, Beloeil"2324# « 3 1/2 disponible Août 2026 » (bandeau d'accueil)25AVAIL_RE = re.compile(r"(\d\s*(?:1/2|½))\s*disponibles?\s*([\w'’éûà]+\s*\d{4}|"26 r"maintenant|imm[ée]diatement)", re.I)27SQFT_RE = re.compile(r"(\d{3,4})\s*(?:à\s*(\d{3,4})\s*)?pieds?\s*carr[ée]s", re.I)28IMG_RE = re.compile(r'(?:src|href)="(/uploads/[^"]+\.(?:jpe?g|png|webp))"', re.I)293031class Beloeil94Connector(BaseConnector):32 source_id = "beloeil_94"33 request_delay = 0.63435 def fetch(self) -> list[Listing]:36 listings: list[Listing] = []37 try:38 html = self.get(BASE + "/").text39 except Exception:40 return listings41 soup = BeautifulSoup(html, "html.parser")42 text = soup.get_text("\n", strip=True)4344 m = AVAIL_RE.search(text)45 if not m:46 return listings # rien d'affiché = aucune disponibilité4748 unit_type = m.group(1).replace(" ", " ")49 availability = f"Disponible {m.group(2)}"5051 # superficie « 685 à 747 pieds carrés » (fourchette de l'immeuble)52 sqft = None53 ms = SQFT_RE.search(text)54 if ms:55 try:56 sqft = float(ms.group(1))57 except ValueError:58 sqft = None5960 # inclusions : liste à puces autour de la fiche de l'immeuble61 amenities: list[str] = []62 lines = text.split("\n")63 try:64 start = next(i for i, l in enumerate(lines) if "électro inclus" in l)65 for l in lines[start:start + 25]:66 if 3 < len(l) < 60 and not l.startswith(("Pour ", "Un ")):67 amenities.append(l)68 except StopIteration:69 pass7071 images = [BASE + u for u in dict.fromkeys(IMG_RE.findall(html))72 if not re.search(r"logo|icon|-\[converted\]", u, re.I)][:15]7374 listings.append(Listing(75 source=self.source_id,76 external_id="guertin-3.5",77 url=BASE + "/",78 title="3½ — Le 94 Vieux-Beloeil",79 address=ADDRESS,80 sector="Vieux-Beloeil",81 city="Beloeil",82 unit_type="3½",83 bedrooms=1,84 bathrooms=1,85 availability=availability,86 area_sqft=sqft,87 description="Immeuble construit en 2020 avec commerce au RDC et "88 "8 unités d'une chambre à coucher au-dessus. "89 "Design moderne et lumineux.",90 amenities=list(dict.fromkeys(amenities))[:15],91 images=images,92 ))93 return listings94