Skip to content

feat: centralizza estrazione e raggruppamento link HTML in link_extractor + probe_html_portal#407

Merged
Gabrymi93 merged 6 commits into
mainfrom
feat/link-extractor-centralized
Jun 25, 2026
Merged

feat: centralizza estrazione e raggruppamento link HTML in link_extractor + probe_html_portal#407
Gabrymi93 merged 6 commits into
mainfrom
feat/link-extractor-centralized

Conversation

@Gabrymi93

Copy link
Copy Markdown
Member

Cosa cambia

Centralizza nel toolkit tutta la logica di estrazione link da HTML, raggruppamento e probe portali, precedentemente duplicata tra toolkit e source-observatory.

Modifiche

Nuovo modulo: toolkit/scout/link_extractor.py

  • DataLink / LinkGroup — dataclass con metadati (url, format, prefix, years)
  • extract_data_links() — estrazione link con metadati, unifica le vecchie implementazioni
  • group_links() — raggruppamento intelligente per prefisso e pattern URL
  • extract_candidate_links() — bridge backward compat

toolkit/scout/probe.py

  • PortalProfile — dataclass profilo portale
  • probe_html_portal() — probe leggero (robots.txt → sitemap → pagine, RSS, JSON:API)
  • fetch_sitemap_pages() — pubblica, estrae URL pagine da sitemap XML
  • Probe su domain root oltre che su base_url (sitemap spesso alla root)

toolkit/scout/http.py

  • Rimosso _AnchorParser duplicato
  • extract_candidate_links() reindirizza a link_extractor

toolkit/mcp/scout_ops.py

  • mcp_html_extract_links arricchito: restituisce data_links[] e groups[]
  • Campi legacy (links, total, formats) mantenuti per backward compat

Impatto downstream

  • source-observatory: branch feat/toolkit-link-extractor corrispondente — importa dal toolkit invece di avere logica propria, rimossa duplicazione _fetch_sitemap, _extract_data_links, _extract_prefix, _extract_years
  • sources_registry.yaml: opencivitas passa da page_url_template a discovery: auto
  • Nessun cambio contratto: tutte le API pubbliche backward compat

Metriche

Tipo: root fix + contract alignment
Problema reale: 2 implementazioni separate di estrazione link HTML (SO + toolkit),
  con estensioni diverse, nessun raggruppamento
Contratto riusato: toolkit.scout.link_extractor — nuovo contratto centrale
Codice rimosso: ~80 LOC in SO html.py + ~45 LOC _fetch_sitemap + ~20 LOC _AnchorParser
Test: 94 pass (SO 29 + toolkit 65)
Rischio residuo: nessuno — API pubbliche backward compatible
Follow-up: ampliare sitemap discovery a /opendata/sitemap.xml per coprire mim_opendata

…ctor

Crea toolkit/scout/link_extractor.py come contratto centrale per
estrazione e raggruppamento di link dati da pagine HTML.

- DataLink e LinkGroup come dataclass con metadati (formato, prefisso, anni)
- extract_data_links() unifica le precedenti implementazioni
- group_links() per raggruppamento intelligente
- extract_candidate_links() mantenuto come bridge backward compat
- http.py: rimosso _AnchorParser, extract_candidate_links redirect
- mcp/scout_ops.py: response arricchito con data_links[] e groups[]

File: +link_extractor.py, __init__.py, http.py, scout_ops.py
Aggiunge probe a costo fisso per scoprire struttura di un portale HTML:
- GET /robots.txt estrae Sitemap: URLs
- Prova path canonici (/sitemap.xml, /sitemap_index.xml)
- Scarica e parse sitemap lista pagine
- Cerca feed RSS e pattern JSON:API nella homepage
- Conta link interni

Risultati su portali reali:
- opencivitas: 575 pagine dalla sitemap
- giustizia_statistiche: 123 pagine dalla sitemap
- aifa, dait: robots.txt trovato ma nessuna sitemap

File: probe.py (+probe_html_portal, +PortalProfile), __init__.py
- _fetch_and_parse_sitemap rinominato a fetch_sitemap_pages pubblico
- Export in __init__.py
- Uso in probe_html_portal aggiornato

File: probe.py, __init__.py
- Se base_url è un path (es. /opendata/...), prova anche la root del
  dominio per robots.txt e sitemap
- Aggiunto /opendata/sitemap.xml ai path canonici
- Dedup degli URL trovati
- fetch_sitemap_pages ora gestisce sitemap index XML
  (<sitemapindex><sitemap><loc>) con fetch ricorsivo
- MCP formats calcolato dal path URL (urlparse) anziché URL grezzo
@Gabrymi93 Gabrymi93 force-pushed the feat/link-extractor-centralized branch from 6f99096 to 002274a Compare June 25, 2026 18:13
@Gabrymi93 Gabrymi93 merged commit 531a871 into main Jun 25, 2026
3 checks passed
@Gabrymi93 Gabrymi93 deleted the feat/link-extractor-centralized branch June 25, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant