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/vallensis.py : connecteur Vallensis (vallensis.ca)5# Condos locatifs neufs à Salaberry-de-Valleyfield (503, rue6# Jacques-Cartier) — bâtiments de 20 unités (647 à 1148 pi²).7# WordPress/Elementor rendu serveur : la page d'accueil affiche une carte8# par typologie (« 3 ½ / À partir de / 1550$/mois »). Granularité :9# typologie (pas d'unités individuelles publiées).10# -----------------------------------------------------------------------------11from __future__ import annotations1213import re1415from bs4 import BeautifulSoup1617from .base import BaseConnector18from ..schema import Listing1920BASE = "https://vallensis.ca"2122ADDRESS = "503, rue Jacques-Cartier, Salaberry-de-Valleyfield"23CITY = "Salaberry-de-Valleyfield"2425TYPE_RE = re.compile(r"^\d\s*½$")26PRICE_RE = re.compile(r"(\d[\d\s ]{2,6})\$\s*/\s*mois", re.I)27IMG_RE = re.compile(r'https://vallensis\.ca/wp-content/uploads/'28 r'[^"\s\\)]+\.(?:jpe?g|png|webp)', re.I)293031class VallensisConnector(BaseConnector):32 source_id = "vallensis"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 lines = soup.get_text("\n", strip=True).split("\n")4344 images = [u for u in dict.fromkeys(IMG_RE.findall(html))45 if not re.search(r"logo|icon|favicon|plan|"46 r"-\d{2,3}x\d{2,3}\.", u, re.I)][:15]4748 # cartes « 3 ½ / À partir de / 1550$/mois » (dans l'ordre du texte)49 for i, line in enumerate(lines):50 if not TYPE_RE.match(line.strip()):51 continue52 window = " ".join(lines[i + 1:i + 4])53 m = PRICE_RE.search(window)54 if not m:55 continue56 unit_type = line.strip().replace(" ", "")57 try:58 price = float(m.group(1).replace(" ", "").replace(" ", ""))59 except ValueError:60 continue61 ext_id = f"valleyfield-{unit_type.replace('½', '.5')}"62 if any(l.external_id == ext_id for l in listings):63 continue64 listings.append(Listing(65 source=self.source_id,66 external_id=ext_id,67 url=BASE + "/",68 title=f"{unit_type} — Vallensis",69 address=ADDRESS,70 city=CITY,71 unit_type=unit_type,72 price=price,73 price_label=f"À partir de {m.group(0)}",74 description="Condos locatifs neufs réalisés par le Groupe "75 "Architecte PDA — bâtiments de 20 unités de 647 "76 "à 1148 pi², esprit épuré et moderne.",77 images=images,78 ))79 return listings80