SPB Git

spb/qc26

Public

Documents partis : rendu Firecrawl avec waitFor (sites JS), date des communiqués, archives < 2022

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Sep 6, 2026) parent 70cedee Browse files

2 changed files +16 −5

modified engine/qc26/connectors/parties/documents.py +15 −4
@@ -177,14 +177,25 @@ def fetch_version(s: Session, doc: PartyDocument) -> DocumentVersion | None:
177 # site rendu en JavaScript (ex. Québec solidaire) : rendu Firecrawl, texte = markdown 177 # site rendu en JavaScript (ex. Québec solidaire) : rendu Firecrawl, texte = markdown
178 try: 178 try:
179 import httpx as _hx 179 import httpx as _hx
180− rr = _hx.post("https://api.firecrawl.dev/v1/scrape", timeout=120, headers={"Authorization": f"Bearer {settings.firecrawl_api_key}"}, 180+ rr = _hx.post("https://api.firecrawl.dev/v1/scrape", timeout=150, headers={"Authorization": f"Bearer {settings.firecrawl_api_key}"},
181− json={"url": doc.url, "formats": ["markdown", "html"], "onlyMainContent": True}) 181+ json={"url": doc.url, "formats": ["markdown", "html"], "onlyMainContent": True, "waitFor": 4000})
182 rr.raise_for_status() 182 rr.raise_for_status()
183 data = rr.json().get("data", {}) 183 data = rr.json().get("data", {})
184 rendered_md = (data.get("markdown") or "").strip() 184 rendered_md = (data.get("markdown") or "").strip()
185 if len(rendered_md) >= 400: 185 if len(rendered_md) >= 400:
186 text = rendered_md 186 text = rendered_md
187 b = (data.get("html") or rendered_md).encode() 187 b = (data.get("html") or rendered_md).encode()
188+ # date de publication en tête de communiqué (« 11 fév 2022 », « 3 septembre 2026 »)
189+ if not doc.published_date:
190+ head = rendered_md[:300]
191+ m = re.search(r"(\d{1,2})\s+([a-zéû]{3,9})\.?\s+(\d{4})", head, re.I)
192+ if m:
193+ doc.published_date = parse_fr_date(f"{m.group(1)} {m.group(2).lower()} {m.group(3)}")
194+ if not doc.published_date:
195+ short = {"fév": "février", "fev": "février", "avr": "avril", "juil": "juillet", "sept": "septembre", "oct": "octobre", "nov": "novembre", "déc": "décembre", "dec": "décembre", "janv": "janvier", "jan": "janvier", "mar": "mars", "mai": "mai", "juin": "juin", "août": "août", "aout": "août"}
196+ mois = short.get(m.group(2).lower().rstrip("."))
197+ if mois:
198+ doc.published_date = parse_fr_date(f"{m.group(1)} {mois} {m.group(3)}")
188 except Exception as e: # noqa: BLE001 199 except Exception as e: # noqa: BLE001
189 log.debug("firecrawl %s : %s", doc.url, e) 200 log.debug("firecrawl %s : %s", doc.url, e)
190 hash_src = text.encode() 201 hash_src = text.encode()
@@ -269,8 +280,8 @@ def analyze_version(s: Session, doc: PartyDocument, v: DocumentVersion, max_chun
269 doc.status = "ignored" 280 doc.status = "ignored"
270 v.analyzed_at = utcnow() 281 v.analyzed_at = utcnow()
271 return 0 282 return 0
272− if OLD_YEAR_RE.search(doc.url): 283+ if OLD_YEAR_RE.search(doc.url) or (doc.published_date and doc.published_date.year < 2022):
273− # document d'archive (daté d'avant 2022 dans l'URL) : conservé et versionné, mais pas de propositions 2026 284+ # document d'archive (daté d'avant 2022) : conservé et versionné, mais pas de propositions 2026
274 doc.status = "archive" 285 doc.status = "archive"
275 doc.doc_type = "archive" 286 doc.doc_type = "archive"
276 v.analyzed_at = utcnow() 287 v.analyzed_at = utcnow()
modified engine/qc26/connectors/polls/registry.py +1 −1
@@ -42,7 +42,7 @@ def firecrawl_scrape(url: str) -> tuple[str, dict]:
42 """Rendu HTML/markdown d'une page par Firecrawl (pages riches en JS). Retourne (html, metadata).""" 42 """Rendu HTML/markdown d'une page par Firecrawl (pages riches en JS). Retourne (html, metadata)."""
43 r = httpx.post("https://api.firecrawl.dev/v1/scrape", timeout=120, 43 r = httpx.post("https://api.firecrawl.dev/v1/scrape", timeout=120,
44 headers={"Authorization": f"Bearer {settings.firecrawl_api_key}"}, 44 headers={"Authorization": f"Bearer {settings.firecrawl_api_key}"},
45− json={"url": url, "formats": ["html", "links"], "onlyMainContent": False}) 45+ json={"url": url, "formats": ["html", "links"], "onlyMainContent": False, "waitFor": 4000})
46 r.raise_for_status() 46 r.raise_for_status()
47 d = r.json().get("data", {}) 47 d = r.json().get("data", {})
48 html = d.get("html") or "" 48 html = d.get("html") or ""
49 49
Menu

Theme