[ka6] fix connecteur boreale.com: depuis le 2026-09-08 ~12h le CMS du site (Craft) émet tous les <loc> de ses sitemaps sur l'IP brute du serveur (https://23.128.160.51/...) au lieu du domaine — cert TLS invalide, donc sitemaps enfants et pages produit inaccessibles et le sync generic tombait à 0 produit (statut ok trompeur, 18 produits purgés). Le domaine www.boreale.com sert toujours les mêmes chemins en 200. Ajout de _rehost() dans generic.py: toute URL <loc> dont l'hôte est une IP littérale (IP_HOST_RE) est ramenée sur le domaine de la boutique. Sync réel: boreale.com ok / 18 produits (= volume historique, +0 ~18 -0); non-régression calmelabo.com (generic, 9 produits, = volume habituel)
1 changed file +12 −1
modified
fabrika/connectors/generic.py
+12 −1
@@ -27,6 +27,7 @@ NON_PRODUCT_RE = re.compile( | ||
| 27 | 27 | r"/panier|/checkout|/contact|/a-propos|/about|/cms|/content/|/faq|/policies|" |
| 28 | 28 | r"/politique|sitemap|\.(?:jpg|png|pdf|css|js)$)", re.I) |
| 29 | 29 | LOC_RE = re.compile(r"<loc>\s*(?:<!\[CDATA\[)?\s*(.*?)\s*(?:\]\]>)?\s*</loc>", re.I | re.S) |
| 30 | +IP_HOST_RE = re.compile(r"^\d{1,3}(?:\.\d{1,3}){3}(?::\d+)?$") | |
| 30 | 31 | |
| 31 | 32 | |
| 32 | 33 | def _clean(s): |
@@ -169,6 +170,16 @@ class GenericConnector(BaseConnector): | ||
| 169 | 170 | max_products = 800 |
| 170 | 171 | use_scrapfly = True # False pendant la détection (vitesse) |
| 171 | 172 | |
| 173 | + def _rehost(self, u): | |
| 174 | + # certains CMS mal configurés (ex. boreale.com, Craft CMS, 2026-09-08) | |
| 175 | + # émettent des <loc> sur l'IP brute du serveur → cert TLS invalide. | |
| 176 | + # On ramène ces URLs sur le domaine de la boutique, qui sert les | |
| 177 | + # mêmes chemins (sitemaps enfants et pages produit vérifiés 200). | |
| 178 | + p = urlparse(u) | |
| 179 | + if IP_HOST_RE.match(p.netloc): | |
| 180 | + return f"{self.base}{p.path}" + (f"?{p.query}" if p.query else "") | |
| 181 | + return u | |
| 182 | + | |
| 172 | 183 | def _sitemap_products(self): |
| 173 | 184 | from . import scrapfly |
| 174 | 185 | seen, out = set(), [] |
@@ -197,7 +208,7 @@ class GenericConnector(BaseConnector): | ||
| 197 | 208 | if not xml: |
| 198 | 209 | continue |
| 199 | 210 | fetched_roots += 1 |
| 200 | − locs = [l.strip() for l in LOC_RE.findall(xml)] | |
| 211 | + locs = [self._rehost(l.strip()) for l in LOC_RE.findall(xml)] | |
| 201 | 212 | child_maps = [l for l in locs if l.endswith(".xml") or "sitemap" in l.lower()] |
| 202 | 213 | if child_maps and depth_left > 0: |
| 203 | 214 | queue = child_maps + queue |
| 204 | 215 | |