> 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/ai/architettura-e-funzionalita-del-chatbot/architettura-e-sicurezza-dei-dati/indicizzazione-dei-contenuti/opencity-ai-chatbot-crawler.md).

# OpenCity AI Crawler

### Cos'è l'OpenCity AI Crawler?

Il crawler di **OpenCity AI** è un web scraper sviluppato da OpenCity Labs per leggere e indicizzare i contenuti web pubblici dei siti della Pubblica Amministrazione, così da renderli disponibili al Chatbot AI.

Visita periodicamente le pagine dei siti comunali, come farebbe un utente reale: legge le pagine, estrae il testo utile e lo salva. Quando una pagina cambia, la aggiorna; quando non è più raggiungibile, la segnala. Il processo è continuo e automatico e non richiede interventi manuali.

### Come identificarlo nei log

Se vedi il nostro crawler nei log del tuo server, lo riconosci dalla seguente stringa `User-Agent`:

```
Mozilla/5.0 (compatible; OpenCityAI-Crawler/1.0; +https://link.opencitylabs.it/ai-chatbot-crawler)
```

Il token da usare nelle regole `robots.txt` è `OpenCityAI-Crawler`.

### Cosa fa?

Quando un crawl parte su un sito, il crawler non conosce in anticipo tutte le pagine: le scopre navigando, proprio come farebbe un utente reale. Parte dalla homepage e segue i link, costruendo progressivamente la mappa del sito. In parallelo usa anche la sitemap XML, se presente, per trovare le pagine più velocemente. Se la sitemap non è dichiarata nel file `robots.txt` ma è comunque nota, puoi inserirla manualmente nella configurazione del sito.

Il crawler rispetta sempre le istruzioni pubblicate nel `robots.txt` e ignora le aree non scansionabili. All'avvio di un crawl puoi però sovrascrivere temporaneamente queste regole, ad esempio per testare aree normalmente escluse.

Tra i contenuti scoperti rientrano anche i file PDF (Portable Document Format): il crawler li scarica e li salva, ma non ne analizza il contenuto interno né segue eventuali link al loro interno.

All'inizio della scansione di un nuovo sito il crawler esegue una fase di calibrazione (*probe*): stabilisce così quante pagine può processare in parallelo senza sovraccaricare il sito. Salva il valore individuato e lo riusa come punto di partenza nelle scansioni successive; dall'interfaccia puoi comunque forzarne uno nuovo quando serve.

Durante la scansione il crawler continua ad adattarsi 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* consecutivi si chiudono senza problemi, riduce gradualmente il ritardo: cerca sempre il ritmo più veloce che il sito è in grado di sostenere.

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: il crawler controlla più spesso le pagine che cambiano frequentemente, molto meno quelle stabili.

Quando arriva il momento di ricontrollare una pagina, il crawler verifica prima se il contenuto è davvero cambiato. Usa le intestazioni HTTP standard e confronta la pagina con quella salvata in precedenza. Solo se rileva una variazione reale, la reindicizza e ne aggiorna la data di ultima modifica. Quel campo indica quindi sempre un cambiamento effettivo del contenuto, non semplicemente l'ultima visita del crawler (indicata invece dal campo *last visited*).

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, sia sulla differenza di quantità di caratteri sia tramite intelligenza artificiale. Quando serve, usa un browser *headless* per ottenere la pagina così come la vedrebbe un utente reale.

Il crawler memorizza la classificazione per ogni pagina, così le scansioni successive non devono ripetere ogni volta lo stesso confronto.

Se una pagina smette di rispondere o restituisce errori ripetuti, il crawler non continua a tentare inutilmente. Dopo alcuni tentativi falliti consecutivi la mette in pausa automaticamente per alcuni giorni; se il problema persiste, allunga progressivamente il blocco. Quando la pagina torna accessibile e risponde correttamente, il crawler rimuove il blocco in automatico e azzera il contatore degli errori.

Ogni giorno alle 02:00 il sistema avvia automaticamente il crawl di tutti i siti disponibili, per mantenerli aggiornati. Se un crawl è già in corso, blocca automaticamente i tentativi successivi sullo stesso sito.

Oltre alle regole automatiche, è possibile intervenire manualmente su singole pagine o su interi percorsi. Per esempio si può:

* forzare una frequenza di riscansione diversa (di base il crawler non ricontrolla le pagine visitate nelle ultime 24 ore);
* aggiungere un file `robots.txt` personalizzato per impostare 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. All'avvio di un crawl è anche possibile impostare un limite massimo di pagine da scansionare, utile per test rapidi su siti molto grandi.

### Comportamento e rispetto del robots.txt

Il nostro crawler:

* rispetta rigorosamente il Web Robots Exclusion Protocol, inclusi `Disallow`, `Allow` e `Crawl-delay`;
* adatta automaticamente la velocità di scansione in base alle risposte del server;
* mantiene un intervallo minimo tra le richieste allo stesso host;
* accede solo a contenuto pubblico, senza entrare in aree autenticate, compilare form o interagire con elementi che richiedono login.

#### Bloccare sezioni specifiche

```
User-agent: OpenCityAI-Crawler
Disallow: /area-riservata/
Disallow: /documenti-interni/
```

#### Impostare un ritardo tra le richieste

```
User-agent: OpenCityAI-Crawler
Crawl-delay: 5
```

#### Bloccare completamente il crawler

```
User-agent: OpenCityAI-Crawler
Disallow: /
```

{% hint style="info" %}
Se il tuo sito ha `Disallow: /` per `User-agent: *` e vuoi che il nostro crawler possa comunque accedere, aggiungi un blocco specifico:

```
User-agent: OpenCityAI-Crawler
Allow: /
```

{% endhint %}

### Verifica dell'autenticità

Il crawler proviene da questi indirizzi IP:

* `3.250.32.208`
* `3.253.249.121`

### Contatti

Per domande, segnalazioni di comportamenti anomali o supporto nella configurazione del `robots.txt`:

* **Sito web:** [www.opencitylabs.it](http://www.opencitylabs.it)
* **Email:** <support@opencitylabs.it>


---

# 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/ai/architettura-e-funzionalita-del-chatbot/architettura-e-sicurezza-dei-dati/indicizzazione-dei-contenuti/opencity-ai-chatbot-crawler.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.
