fix(hanlon): volume reel 3670 (X-WP-Total wp/v2/rps_listing) + garde page-1
- le ~22k du scout comptait les occurrences CSS de l empreinte au-dela de la fin reelle de l archive -> registre corrige (pp=100, 45 pages max) - garde anti page-vide intermittente : 3 reprises + variantes d URL sur la page 1, sinon RuntimeError (un 0-resultat retirait tout l inventaire)
2 changed files +21 −3
modified
data/canada_agencies.json
+2 −3
@@ -113,10 +113,9 @@ | ||
| 113 | 113 | "name": "hanlonrealty.ca (Newfoundland and Labrador)", |
| 114 | 114 | "site": "https://hanlonrealty.ca", |
| 115 | 115 | "archive": "listing", |
| 116 | − "max_pages": 2400, | |
| 116 | + "max_pages": 45, | |
| 117 | 117 | "province": "Newfoundland and Labrador", |
| 118 | − "note": "Recensement CANADA 2026-08-27 : ~22 000 fiches (board NL complet). posts_per_page plafonne a ~3 500 items -> pagination NATIVE 10/page. RealtyPress/DDF.", | |
| 119 | − "page_size": 10 | |
| 118 | + "note": "Recensement CANADA 2026-08-27 corrigé : 3 670 fiches réelles (X-WP-Total de /wp-json/wp/v2/rps_listing) — le ~22k initial comptait les occurrences CSS de l'empreinte au-delà de la fin. posts_per_page=100, ~37 pages. RealtyPress/DDF NL." | |
| 120 | 119 | }, |
| 121 | 120 | { |
| 122 | 121 | "id": "rp_ag_denisedunnrealtor", |
modified
immoka/connectors/realtypress.py
+19 −0
@@ -115,6 +115,25 @@ class _RealtyPress(BaseConnector): | ||
| 115 | 115 | body = self.get(url).text |
| 116 | 116 | except Exception: |
| 117 | 117 | break |
| 118 | + if page == 1 and not _CARD_RE.search(body): | |
| 119 | + # page 1 vide par intermittence (hanlonrealty sert parfois un | |
| 120 | + # gabarit sans cartes) : réessayer, puis variantes d'URL — un | |
| 121 | + # échec ici ferait retirer TOUTES les fiches de la source | |
| 122 | + import time as _t | |
| 123 | + for alt in (url, f"{base}/{self.archive}/?posts_per_page=100", | |
| 124 | + f"{base}/{self.archive}/page/2/{pp}"): | |
| 125 | + _t.sleep(2.0) | |
| 126 | + try: | |
| 127 | + body = self.get(alt).text | |
| 128 | + except Exception: | |
| 129 | + continue | |
| 130 | + if _CARD_RE.search(body): | |
| 131 | + break | |
| 132 | + if not _CARD_RE.search(body): | |
| 133 | + raise RuntimeError( | |
| 134 | + f"{self.source_id}: archive sans cartes après reprises " | |
| 135 | + "(page vide intermittente ?) — sync abandonné pour " | |
| 136 | + "protéger l'inventaire") | |
| 118 | 137 | cards = self._cards(body) |
| 119 | 138 | if not cards: |
| 120 | 139 | break |
| 121 | 140 | |