# ----------------------------------------------------------------------------- # Lou-Ka — Location court terme # connectors/domesstcome.py : Dômes St-Côme (domesstcome.com) — 4 dômes # géodésiques avec spa privé et vue panoramique à Saint-Côme (Lanaudière). # # Méthode : sitemap Wix (index) → dynamic-domes_*-sitemap.xml → 4 URLs # /domes/ + lastmod (clé du cache détail). Pages Wix statiques : # -

= nom du dôme ; sous-titre « Vue panoramique | Spa privé » ; # - « À partir de 370$/nuit » → price_night ; # - sections LITS / AUTRES / CUISINE / À L'EXTÉRIEUR / SALLE DE BAIN # (texte riche Wix) → amenities ; beds = nb de « Lit … » sous LITS ; # - CITQ (6 chiffres) dans le pied de page ; # - images : médias wixstatic ~mv2 servis en grand (w ≥ 900) — la galerie # Pro Gallery est chargée en JS, seuls les héros sont statiques. # ----------------------------------------------------------------------------- from __future__ import annotations import html as _html import re from ..schema import StListing from .base import StConnector SITE = "https://www.domesstcome.com" SITEMAP = SITE + "/sitemap.xml" _SECTIONS = ("LITS", "AUTRES", "CUISINE", "À L'EXTÉRIEUR", "SALLE DE BAIN") _TAG_RE = re.compile(r"<[^>]+>") def _lines(fragment: str) -> list[str]: """HTML riche Wix → lignes de texte propres (CSS inline filtré).""" txt = re.sub(r"\|(?:\s*\|)+", "\n", re.sub(r"\s+", " ", _TAG_RE.sub("|", fragment))) out = [] for x in txt.split("\n"): x = _html.unescape(x).strip(" |").strip() x = re.sub(r"\s*\|\s*", " | ", x) if x and len(x) > 2 and "{" not in x and "--" not in x: out.append(x) return out class DomesStCome(StConnector): source_id = "domesstcome" request_delay = 1.0 # -- page détail ---------------------------------------------------------- def _detail(self, url: str) -> dict: h = self.get(url).text d: dict = {} m = re.search(r"(?s)]*>(.*?)

", h) if m: d["title"] = _html.unescape( re.sub(r"\s+", " ", _TAG_RE.sub(" ", m.group(1)))).strip() m = re.search(r"À partir de\s*(\d+)\s*\$\s*/\s*nuit", h) if m: d["price_night"] = float(m.group(1)) m = re.search(r"CITQ\D{0,25}(\d{6})", h) if m: d["citq"] = m.group(1) # sous-titre (« Vue panoramique | Spa privé ») → description i, j = h.find(" 80: continue amen.append(x) if current == "LITS" and re.match(r"Lit\b", x, re.I): beds += 1 if amen: d["amenities"] = amen if beds: d["beds"] = float(beds) # images : médias wixstatic servis en grand (héros) big: dict[str, int] = {} for mid, w in re.findall(r"static\.wixstatic\.com/media/" r"([\w~%.]+)/v1/fill/w_(\d+)", h): w = int(w) if w >= 900: big[mid] = max(big.get(mid, 0), w) imgs = [f"https://static.wixstatic.com/media/{mid}" for mid in big][:15] if imgs: d["images"] = imgs return d # -- contrat -------------------------------------------------------------- def fetch(self) -> list[StListing]: index = self.get(SITEMAP).text entries: list[tuple[str, str]] = [] for sub in re.findall(r"([^<]+)", index): if "dynamic-domes" not in sub: continue xml = self.get(sub).text entries += re.findall(r"(?s)\s*([^<]+)" r"(?:\s*([^<]*))?", xml) listings: list[StListing] = [] vus: set[str] = set() for url, lastmod in entries: m = re.match(r"https://www\.domesstcome\.com/domes/([^/]+)/?$", url) if not m: continue slug = m.group(1) if slug in vus: continue vus.add(slug) det = self.detail(slug, lastmod or "v1", lambda u=url: self._detail(u)) title = det.get("title") or "" if not title: continue price = det.get("price_night") listings.append(StListing( source=self.source_id, external_id=slug, url=url, title=title, property_type="Dôme", city="Saint-Côme", region="Lanaudière", price_night=price, price_label=f"À partir de {price:g} $ / nuit" if price else "", beds=det.get("beds"), citq=det.get("citq") or "", description=det.get("description") or "", amenities=det.get("amenities") or [], details={"domain": "Dômes St-Côme"}, images=det.get("images") or [], )) return listings