Spider Tree
Web crawler e directory tree generator desktop in Python con GUI moderna. Mappa la struttura gerarchica di qualsiasi sito web filtrando asset e media, esportando la mappa del sito in report interattivi (HTML, JSON, Markdown).

Spider-Tree: crawler gerarchico ad alte prestazioni
Il contesto e il problema
L'idea è nata durante la fase preliminare di restyling di un sito web di medie dimensioni. Per stimare i tempi di migrazione e riorganizzare l'architettura delle informazioni serviva un dato di partenza banale ma critico: capire esattamente quali e quante pagine componessero il dominio.
Gli strumenti a disposizione avevano limiti pratici evidenti:
- I tool SEO tradizionali: software come Screaming Frog o script analoghi esportano fogli CSV con migliaia di record non strutturati. Analizzare un elenco piatto non restituisce alcuna percezione visiva della gerarchia, dei livelli di profondità o dei rami logici.
- I crawler basati su browser: avviare istanze headless di Chromium solo per estrarre tag
<a>consuma facilmente tra gli 800 MB e gli 1.5 GB di memoria prima ancora di iniziare il lavoro effettivo. - Le utility di sistema: il comando
treesu terminale è perfetto per leggibilità, ma è vincolato al file system locale e non ha corrispondenze native per il web.
L'obiettivo era quindi costruire uno strumento snello: un crawler mirato a scartare asset statici (immagini, CSS, script, font) per concentrarsi solo sulle pagine HTML navigabili, mappando la struttura del sito con la stessa logica di un albero di directory.
I nodi critici dell'architettura HTTP
Trattare il web come un file system incontra subito due problemi tecnici dovuti alla natura a grafo della rete.
1. Loop e ambiguità degli URI
Un sito genera facilmente percorsi multipli verso la stessa identica risorsa:
- Frammenti di pagina (
/servizi#prezzirispetto a/servizi) - Percorsi relativi (
../../chi-siamo) - Gestione non uniforme del trailing slash (
/blogrispetto a/blog/) - Discrepanze tra sottodomini (
www.dominio.itvsdominio.it) e parametri di query string (tracking, filtri).
Senza una normalizzazione a monte, il crawler rischia cicli di visita infiniti o una proliferazione incontrollata di duplicati nello stesso ramo.
2. Le directory logiche non fisiche
Su disco, se esiste /progetti/web/portfolio.html, la directory intermedia /progetti/web/ esiste fisicamente. Sul web no: un server può servire 200 OK sull'endpoint completo /progetti/web/portfolio.html, ma restituire 404 o un redirect se si interroga direttamente /progetti/web/.
Costruire un albero continuo richiede una strategia per gestire questi nodi intermedi mancanti senza interrompere la gerarchia visiva.
Scelte implementative: Trie e nodi dedotti
La soluzione consiste nell'adozione di un Trie affiancato da una pipeline di normalizzazione deterministica.
[ Root: https://example.com ]
│
┌─────────────┴─────────────┐
▼ ▼
/prodotti/ (inferred) /contatti/ (200 OK)
│
┌─────────┴─────────┐
▼ ▼
software/ (inferred) hardware/ (200 OK)
│
▼
antivirus.html (200 OK)
- Normalizzazione: ogni URL estratto viene ripulito da ancore, validato rispetto al perimetro del dominio ed elaborato in formato assoluto.
- Nodi dedotti (inferred): inserendo nel Trie un percorso come
/prodotti/software/antivirus.html, la stringa viene segmentata sui separatori/. Se i segmenti intermedi non corrispondono a pagine scansionate con successo, vengono istanziati come nodi fittizi. In questo modo l'albero mantiene la coerenza strutturale. - Gestione del carico di rete: il crawler definisce timeout rigidi per le connessioni, applica filtri di confine sul dominio per evitare link esterni indesiderati e sfrutta le risorse standard messe a disposizione dai webmaster (
robots.txtesitemap.xml).
Architettura e scelte di stack
La scelta progettuale principale è stata ridurre al minimo le dipendenze esterne.
┌─────────────────────────────────────────────────────────────┐
│ GUI Desktop (CustomTkinter) │
│ Wizard a 4 step - Dark/Light Mode │
└──────────────────────────────┬──────────────────────────────┘
│ Disaccoppiamento thread
┌──────────────────────────────▼──────────────────────────────┐
│ Spider-Tree Core Engine │
│ Python Standard Library (zero package esterni) │
│ urllib - html.parser - concurrent.futures - xml │
└──────────────────────────────┬──────────────────────────────┘
│
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
[ ASCII Tree ] [ Markdown / JSON ] [ Standalone HTML ]
1. Motore di scansione: libreria standard
Il core è sviluppato interamente con i moduli nativi di Python (urllib, html.parser, concurrent.futures, xml.etree). Questo elimina il peso e la complessità di runtime di tool come Scrapy o Playwright, assicurando:
- Avvio immediato.
- Esecuzione portabile senza virtual environment pesanti o conflitti di versione.
- Consumo di memoria minimo.
2. Interfaccia grafica (CustomTkinter)
Per evitare il sovraccarico tipico di un'applicazione Electron, la GUI è realizzata con CustomTkinter e Pillow: interfaccia desktop nativa, tempi di caricamento ridotti e possibilità di esecuzione diretta tramite script di avvio.
3. Flusso operativo
[ 1. Target URL ] ──► [ 2. Formato ] ──► [ 3. Scansione Live ] ──► [ 4. Export ]
(Scegli (Worker separato, (ASCII, JSON,
output) timer e contatori) Markdown, HTML)
Il flusso segue passaggi lineari:
- Target: inserimento dell'URL radice.
- Formato: selezione dei file di output desiderati.
- Esecuzione: tracciamento in tempo reale con timer e metriche su pagine processate e in coda.
- Esportazione: salvataggio del report su disco o apertura immediata.
Caratteristiche funzionali del motore
Discovery combinata
Prima del parsing dei link nel codice HTML, lo script interroga robots.txt ed estrae gli URL presenti nelle sitemap indicate (inclusi indici ricorsivi sitemapindex). Questo passaggio definisce una base di partenza per raggiungere anche pagine prive di collegamenti interni nel menu o nel body.
[ Dominio Target ]
│
├─► [ Fase 1: Discovery Passiva ] ──► robots.txt ──► sitemap.xml ──┐ (Seed URLs)
│ ▼
└─► [ Fase 2: Crawling Attivo ] ◄──────────────────────────────────┘
│
├─► ThreadPoolExecutor (concorrente, max 3 MB per risorsa)
├─► Normalizzazione & Deduplicazione con Lock
└─► Popolazione del TrieTree (nodi reali + inferred)
Gestione della concorrenza
Il recupero delle pagine e la popolazione dell'albero avvengono tramite un pool di thread gestito con ThreadPoolExecutor. L'accesso alle code di visita e alle strutture condivise è sincronizzato via primitive di blocco (threading.Lock) per evitare richieste duplicate. Per non saturare la memoria con asset anomali, il download viene troncato se supera una soglia predefinita per risorsa (3 MB). L'elaborazione gira su un thread dedicato, mantenendo l'interfaccia grafica sempre responsiva.
Output HTML autonomo
L'esportazione HTML produce un singolo file statico che incorpora stile e script minimi senza riferimenti a CDN o risorse esterne:
- Filtro istantaneo da campo di testo per isolare singoli percorsi.
- Struttura a nodi espandibili e collassabili per consultare solo i rami necessari.
- Indicazione esplicita degli status code HTTP (200, 301, 404).
Metriche a confronto
| Parametro | Ambienti headless (Chromium) | Spider-Tree |
|---|---|---|
| Occupazione RAM media | 800 MB — 1.5 GB | 20 — 50 MB |
| Tempo di inizializzazione | 3 — 8 secondi | Meno di 0.5 secondi |
| Dipendenze motore | Binari browser e librerie Node/Python | Nessuna (Libreria standard) |
| Dimensione report HTML | Directory con dipendenze collegate | Inferiore a 100 KB (file unico) |
Considerazioni tecniche e sviluppi futuri
L'impiego del Trie ha dimostrato come la strutturazione corretta dei dati in memoria renda superfluo l'uso di framework complessi per compiti di questo tipo. Il risparmio di risorse permette di eseguire scansioni complete anche su macchine con limitazioni hardware stringenti.
Le prossime implementazioni prevedono:
- Modulo headless opzionale: integrazione su richiesta di un renderer JS per mappare Single Page Application basate su framework client-side.
- Motore di diff strutturale: utility CLI/GUI per confrontare due versioni dello stesso albero (es. pre e post migrazione) e tracciare modifiche ai percorsi, redirect e codici di errore.
- Rappresentazione a grafo orientato: opzione di esportazione per visualizzare visivamente la densità dei collegamenti interni oltre alla semplice gerarchia a directory.
Hai un'idea o una sfida tecnica da sviluppare?
Progetto e sviluppo applicazioni web moderne, piattaforme scalabili e architetture cloud su misura per le tue esigenze.