> For the complete documentation index, see [llms.txt](https://docs.opencityitalia.it/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opencityitalia.it/stanza-del-cittadino/installazione-e-manutenzione/open-city-crawler/come-funziona.md).

# Come funziona

## Scoperta dei contenuti

Quando un crawl parte su un sito, il crawler non conosce in anticipo tutte le pagine. Le scopre navigando.

Parte dalla homepage, trova i link, li segue e costruisce progressivamente la mappa del sito.

In parallelo usa anche la sitemap XML, se presente, per trovare più velocemente le pagine. Se la sitemap non è dichiarata nel file `robots.txt` ma è nota, può essere inserita manualmente nella configurazione del sito.

Il crawler rispetta le istruzioni pubblicate nel file `robots.txt`. Se un'area del sito non è scansionabile, viene ignorata.

All'avvio di un crawl è anche possibile sovrascrivere temporaneamente queste regole. Questa opzione è utile, ad esempio, per testare aree normalmente escluse.

Si possono configurare i tipi di link che si vogliono scoprire per ogni sito (PDF, XML, CSV, DOCX, JSON etc) Quando il crawler trova un link a uno di questi, lo scarica e lo salva. Non analizza però il contenuto interno del file e non segue eventuali link presenti al suo interno.

## Coda di scansione per siti già conosciuti

Per un sito già scansionato, il crawler consulta prima la sua cronologia. Non riparte da un elenco vuoto, quando l'archivio storico è disponibile.

Esclude subito le pagine che non richiedono un nuovo controllo. La decisione usa l'ultima verifica e la frequenza con cui la pagina cambia.

Lo stesso meccanismo regola la finestra di validità descritta più avanti. Le pagine stabili non entrano nella coda di scansione finché non serve riconsiderarle.

Questo evita lavoro non necessario. Le scansioni diventano più rapide ed efficienti quando il sito resta stabile nel tempo.

## Fase di probe e ritmo adattivo

All'inizio della scansione di un nuovo sito il crawler esegue una fase di calibrazione.

Serve a capire quante pagine può processare in parallelo o in un lasso di tempo breve senza sovraccaricare il sito.

Una volta individuato, questo valore viene salvato e riutilizzato come punto di partenza nei run successivi.

Se necessario, è possibile forzare un nuovo *probe* dall'interfaccia.

Durante la scansione, il crawler si adatta comunque continuamente al comportamento del sito.

Se riceve segnali di rallentamento, come errori `429` o `503`, aumenta automaticamente il tempo di attesa tra una richiesta e l'altra.

Se invece più *batch* di richieste consecutivi si chiudono senza problemi, riduce gradualmente questo ritardo.

L'obiettivo è trovare il ritmo più veloce possibile che il sito sia in grado di sostenere.

Il ritmo viene gestito a livello di infrastruttura ospitante. Il crawler riconosce gli indirizzi IP usati da un sito nel tempo e li raggruppa.

In questo modo, siti sullo stesso cluster condividono il limite di velocità. Il limite resta valido anche se il cluster usa indirizzi IP diversi durante la scansione.

## Aggiornamento dei contenuti

Il crawler non riscansiona una pagina se non serve.

Ogni pagina ha una finestra di validità che si allunga o si accorcia automaticamente in base alla sua storia. Le pagine che cambiano spesso vengono controllate più di frequente. Quelle stabili molto meno.

Questo approccio concentra le risorse dove ci sono cambiamenti reali.

Ogni pagina ha un codice univoco derivato dal suo indirizzo.

Quando arriva il momento di ricontrollarla, il crawler verifica se il contenuto è davvero cambiato. Confronta il testo principale estratto con quello salvato in precedenza.

Il confronto esclude intestazione, piè di pagina e menu condivisi. Un aggiornamento al menu o a un banner non modifica quindi tutte le pagine del sito.

Per la homepage, il confronto usa invece la pagina intera. In questo caso, gli elementi comuni costituiscono una parte importante del contenuto.

Il contenuto completo viene sempre conservato. Il testo principale serve soltanto a rilevare le modifiche.

Solo se rileva una variazione reale, la pagina viene reindicizzata e la data di ultima modifica nella dashboard viene aggiornata.

Questo significa che quel campo indica sempre un cambiamento effettivo del contenuto. Non indica semplicemente l'ultima visita del crawler (indicata dal campo *last visited*).

Nello specifico:

* Se il crawler confronta il contenuto della pagina e trova una differenza rispetto alla visita precedente, usa la data in cui quella variazione è stata rilevata. È la fonte più affidabile perché dipende dal contenuto effettivo.
* Se la sitemap XML del sito dichiara una data, questa viene salvata all'avvio del crawl e usata come riferimento quando il crawler non ha ancora rilevato modifiche dirette.
* Se il server HTTP include l'intestazione Last-Modified, questa viene conservata come fallback quando le altre due fonti non sono disponibili.

Se una fonte smette di fornire informazioni — per esempio il server smette di includere l'intestazione o la sitemap viene rimossa — il valore salvato in precedenza viene preservato automaticamente.

Quando una data proviene solo dalla sitemap, il crawler esegue comunque controlli diretti a intervalli regolari. In questo modo, date non attendibili non possono rimandare indefinitamente la verifica del contenuto.

## Architettura

Il crawler usa tre database con ruoli distinti.

* **Database permanente di gestione** — conserva la configurazione dei siti, lo stato e la cronologia delle pagine, le eccezioni manuali e i dati delle scansioni. Questi dati alimentano le dashboard.
* **Database in memoria** — viene usato durante una scansione per gestirne il funzionamento. Contiene le pagine ancora da visitare, quelle già incontrate, il segnale che impedisce scansioni doppie e i dati operativi per adattare il ritmo di scansione, inclusi gli indirizzi IP rilevati.
* **Database dei contenuti** — conserva le pagine scaricate e il testo principale estratto. I contenuti vengono aggiornati solo quando cambiano realmente.

### Se il database permanente non è disponibile

Il database permanente migliora l'efficienza e alimenta le dashboard. Non è necessario per eseguire la scansione di base.

Se non è raggiungibile, il crawler continua a leggere e salvare le pagine nel database dei contenuti. Considera però ogni pagina come nuova, perché non può escludere in anticipo quelle già note e stabili.

I dettagli di quella scansione non sono disponibili nelle dashboard. Sono infatti letti dal database permanente.

Quando il database torna disponibile, il crawler riprende automaticamente il comportamento normale. Non serve alcun intervento manuale.

## Siti con contenuti JavaScript

Alcuni siti caricano i contenuti principali tramite JavaScript. In questi casi il testo non è visibile nella versione HTML statica della pagina.

Il crawler rileva automaticamente questa situazione confrontando le due versioni della pagina.

Quando serve, usa un browser *headless* per ottenere la pagina così come la vedrebbe un utente reale.

Il contenuto della pagina con JS caricato e il plain HTML vengono confrontati sia controllando la differenza di quantità di caratteri sia con un confronto attraverso AI.

Questa classificazione viene memorizzata per ogni pagina. I run successivi non devono quindi ripetere ogni volta lo stesso confronto.

## Gestione degli errori

Se una pagina smette di rispondere o restituisce errori ripetuti, il crawler non continua a tentare inutilmente.

Dopo alcuni tentativi falliti consecutivi, la pagina viene messa in pausa automaticamente per alcuni giorni.

Se il problema persiste anche dopo la pausa, il blocco si allunga progressivamente.

Quando la pagina torna accessibile e risponde correttamente, il blocco viene rimosso in automatico e il contatore degli errori viene azzerato.

Invece se la pagina non torna accessibile, al terzo blocco progressivo, viene automaticamente eliminata delle nostre basi di dati, per non mantenere contenuto obsoleto.

## Perché una pagina può non essere indicizzata

Una pagina può essere esclusa dall'archivio per motivi diversi. L'esclusione non indica necessariamente un errore.

Il crawler non indicizza una pagina quando:

* il file `robots.txt` ne vieta la scansione;
* il sito richiede esplicitamente di non indicizzarla;
* il file supera la dimensione massima consentita;
* il formato del file non è abilitato per quel sito;
* la pagina è una copia esatta di un contenuto già indicizzato nello stesso sito.

Per i casi eccezionali, è possibile forzare l'indicizzazione di una singola pagina. L'eccezione riguarda solo quella pagina e non modifica la configurazione generale del sito.

## Crawl giornalieri

Ogni giorno alle 02:00 Windmill avvia automaticamente il crawl di tutti i siti disponibili per mantenerli aggiornati.

Se un crawl è già in corso, il sistema blocca automaticamente i tentativi successivi sullo stesso sito.

## Interruzioni, riavvii e crawl concorrenti

Qualsiasi interruzione di un crawl comporta un reset completo. Vale sia per l'arresto dalla dashboard sia per un problema tecnico imprevisto.

Il sistema azzera le pagine scoperte e ancora in coda per quel sito. Il crawl successivo riparte sempre dalla homepage.

Le pagine già lette e salvate restano disponibili nel database dei contenuti. Viene perso soltanto il lavoro in corso non ancora completato.

Il crawler impedisce sempre due scansioni contemporanee sullo stesso sito. Se una scansione è già attiva, il secondo tentativo viene segnalato come già in corso e non parte.

Il controllo riguarda il singolo sito. Non blocca le scansioni degli altri siti dello stesso ente.

Se il database permanente di gestione non è raggiungibile, il crawler continua a leggere e salvare le pagine. In quel momento non può usare alcune informazioni storiche, come la frequenza di rivisita già calcolata, ma non interrompe il lavoro in corso.

## Opzioni manuali

Puoi intervenire manualmente su singole pagine o su interi percorsi.

Per esempio, puoi:

* forzare una frequenza di riscansione diversa;
* aggiungere un file `robots.txt` personalizzato per specificare un limite di velocità o bloccare la scansione di certi percorsi;
* forzare un crawl da zero ignorando le regole per le pagine già visitate.

Queste opzioni convivono con quelle automatiche e hanno precedenza su di esse.

Per ogni sito è possibile impostare un limite massimo di pagine indicizzate. Il limite definisce la capacità dell'archivio per quel sito e resta valido nelle scansioni successive.

Se non viene impostato alcun limite, il numero di pagine indicizzabili è illimitato. OpenCity può definire il limite più adatto per ogni sito.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.opencityitalia.it/stanza-del-cittadino/installazione-e-manutenzione/open-city-crawler/come-funziona.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
