SPB Git forge

spb/job-ka

Public
229commits 1branches 0releases
38.1 MBsize
maindefault branch
1 h agolast push
HTML 82.1% Python 14.6% TypeScript 1.9% CSS 1% JavaScript 0.5%

[ka6] fix connecteur motosillimitees: garde anti faux-zéro dans la plateforme jazzhr — la page liste renvoie parfois 200 sans la structure du jobboard (constaté 2026-09-04 10h09, sync à 0 en 0,2 s alors que 2 offres réelles), le marqueur 'resumator' est maintenant exigé avec retry+backoff sinon erreur explicite dans sync_log; sync rejoué: 2 offres (médiane 2.0), rotation d'offres de l'employeur absorbée

Simon-Pierre Boucher committed 20 days ago (Sep 4, 2026) parent 86fc781

1 changed file +26 −2

modified jobka/connectors/jazzhr.py +26 −2
@@ -5,7 +5,7 @@
5 5 # Fichier : jobka/connectors/jazzhr.py
6 6 # Rôle : Classe de plateforme JazzHR (applytojob.com) — liste HTML publique
7 7 # /apply/ + JSON-LD JobPosting des pages détail (lieu, salaire…)
8 −# Créé : 2026-08-25 Modifié : 2026-08-25
8 +# Créé : 2026-08-25 Modifié : 2026-09-04
9 9 # =============================================================================
10 10 """Plateforme JazzHR (<org>.applytojob.com), répandue chez les PME.
11 11
@@ -21,6 +21,7 @@ from __future__ import annotations
21 21
22 22 import os
23 23 import re
24 +import time
24 25
25 26 from ..schema import JobPosting, is_quebec_location
26 27 from . import _jsonld
@@ -52,8 +53,31 @@ class JazzHRConnector(BaseConnector):
52 53 node = _jsonld.extract_jobposting(html)
53 54 return _jsonld.jobposting_fields(node) if node else {}
54 55
56 + def _fetch_list(self) -> str:
57 + # JazzHR renvoie parfois 200 avec une page sans la structure du
58 + # jobboard (constaté le 2026-09-04 sur motosillimitees : sync à
59 + # 0 offre en 0,2 s alors que la page réelle en listait 2). Une
60 + # vraie page liste porte toujours le marqueur « resumator »
61 + # (classe body resumator-jobboard-home), même sans aucune offre :
62 + # son absence = page challenge/erreur, pas une liste vide — on
63 + # retente avec backoff puis on lève une erreur explicite plutôt
64 + # que de rapporter un faux « 0 offre ».
65 + last = ""
66 + for attempt in range(3):
67 + resp = self.get(f"{self._base}/apply/")
68 + html = resp.text
69 + if "resumator" in html:
70 + return html
71 + last = (f"HTTP {resp.status_code}, {len(html)} octets, "
72 + f"content-type {resp.headers.get('content-type')}")
73 + if attempt < 2:
74 + time.sleep(10 * (attempt + 1))
75 + raise RuntimeError(
76 + f"jazzhr {self.ORG}: page liste sans structure jobboard "
77 + f"après 3 essais ({last})")
78 +
55 79 def fetch(self) -> list[JobPosting]:
56 − html = self.get(f"{self._base}/apply/").text
80 + html = self._fetch_list()
57 81 out: list[JobPosting] = []
58 82 details_used = 0
59 83 seen: set[str] = set()
60 84