Leggere un access log in 30 minuti: che cosa fanno davvero i robot di IA su un sito
Nessuna dashboard dice a un editore se ChatGPT, Claude o Perplexity leggono le sue pagine. La Search Console copre solo Google, e i motori generativi non forniscono nulla. L'unica fonte che esiste è il registro delle richieste del server, l'access log, che ogni hosting produce e che quasi nessuno apre. In mezz'ora, con gli strumenti presenti su qualunque server Linux, vi si legge chi viene, per fare che cosa, e che cosa il server gli ha risposto. Ecco il metodo che applichiamo, fase per fase, con i comandi. Come si divide la mezz'ora: cinque minuti per l'estrazione, cinque per il conteggio per robot, dieci per la verifica degli indirizzi, cinque per i codici di risposta, cinque per i percorsi e la cadenza.
Tutti i comandi che seguono presuppongono un log in formato combined e si lanciano sul file estratto alla fase 1. Usano soltanto grep, awk, sort e uniq.
Che cosa contiene una riga
Un access log in formato combinato, quello predefinito di Apache e di nginx, contiene una riga per richiesta. Ogni riga dà, nell'ordine: l'indirizzo IP del client, la data e l'ora, il metodo e il percorso richiesti, il codice di risposta, la dimensione inviata, il referer e lo user-agent. Per l'analisi dei robot contano quattro campi:
| Campo | Che cosa permette |
|---|---|
| Indirizzo IP | Verificare che il robot sia davvero quello che dichiara di essere |
| Percorso | Sapere quali pagine vengono lette, e quali non lo sono mai |
| Codice di risposta | Sapere se il robot ha ottenuto la pagina, un reindirizzamento, un errore o un rifiuto |
| User-agent | Identificare la famiglia e il ruolo del robot |
Prima verifica, prima di ogni analisi: l'indirizzo IP registrato è quello del visitatore o quello di un intermediario? Dietro un CDN o un proxy il server vede l'indirizzo dell'intermediario, a meno che non sia configurato per leggere l'header che trasporta l'indirizzo di origine. Se tutte le richieste sembrano venire da qualche decina di indirizzi, la fase di verifica descritta più avanti non sarà possibile, e occorre correggere la configurazione prima di continuare. Abbiamo descritto questa trappola in «Cosa il firewall nasconde ai log».
Fase 1: isolare il periodo e i robot di IA
Si lavora su un periodo completo, sette giorni come minimo, perché i robot di IA non passano tutti i giorni e le conclusioni tratte da ventiquattro ore sono quasi sempre false. Si estraggono poi le righe il cui user-agent contiene uno dei token pubblicati dai fornitori: GPTBot, ChatGPT-User, OAI-SearchBot per OpenAI; ClaudeBot, Claude-User, Claude-SearchBot per Anthropic; PerplexityBot e Perplexity-User per Perplexity; Google-Extended non compare nei log, perché è un token di robots.txt e non un robot. Gli elenchi di riferimento sono quelli di OpenAI, di Anthropic e di Perplexity.
Basta un filtro grep su questi token, diretto verso un file di lavoro. Su una testata di dimensioni medie si ottengono da qualche centinaio a qualche migliaio di righe alla settimana.
zcat -f access.log* \
| grep -E 'GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User' \
> ia.log
Fase 2: contare per robot e per ruolo
Ogni fornitore gestisce più robot che non fanno la stessa cosa, ed è la distinzione più utile di tutta l'analisi. Un robot di addestramento raccoglie pagine per modelli futuri. Un robot di ricerca costruisce un indice per rispondere alle domande. Un robot su richiesta va a cercare una pagina per una persona che pone una domanda all'assistente. Abbiamo dettagliato i ruoli e i token in «robots.txt e IA».
Si contano quindi le righe per user-agent e le si raggruppa in tre colonne: addestramento, ricerca, agente utente. Il risultato si legge così:
- Solo richieste di addestramento significano che il sito viene raccolto, ma nulla dice che venga citato.
- Richieste di ricerca indicano che il sito è indicizzato dal motore generativo, condizione necessaria per essere citati.
- Le richieste di agente utente sono il segnale più prezioso: ciascuna corrisponde a una domanda di un utente per la quale l'assistente è andato a cercare quella pagina.
grep -oE 'GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User' ia.log \
| sort | uniq -c | sort -rn
Fase 3: verificare che i robot siano autentici
Uno user-agent si dichiara liberamente. Qualunque script può presentarsi come GPTBot. Prima di contare si verifica che gli indirizzi IP appartengano agli intervalli pubblicati da ciascun fornitore: OpenAI, Anthropic e Perplexity pubblicano file di intervalli, e Google documenta la verifica dei suoi robot tramite reverse DNS. Si estraggono gli indirizzi distinti per user-agent, li si confronta con gli intervalli e si scarta ciò che non vi figura. Il metodo completo, con le sue trappole, è in «Un robot è davvero quello che dichiara di essere?».
Sulla maggior parte dei siti su cui svolgiamo audit ne troviamo: richieste che si dichiarano Googlebot o GPTBot da indirizzi che non appartengono né a Google né a OpenAI. Non abbiamo un dato di volume pubblicabile da associarvi; il test, invece, costa un comando. Contare senza verificare significa rischiare di misurare scraper travestiti.
# gli indirizzi distinti di un robot, da confrontare con gli intervalli pubblicati
awk '/GPTBot/ {print $1}' ia.log | sort -u
Fase 4: leggere i codici di risposta
Per ogni robot autentico si ripartiscono i codici di risposta. Il quadro atteso su un sito sano è quasi interamente in 200, con qualche 304 se il server gestisce le richieste condizionali, e qualche 404 su URL ritirate. Tre anomalie meritano un'azione:
| Osservazione | Causa probabile | Azione |
|---|---|---|
| Molti 301 o 302 | Il robot segue vecchie URL, oppure la sitemap dichiara indirizzi non canonici | Correggere la sitemap, dichiarare solo le URL finali |
| 403 o 429 per un robot autentico | Una regola di firewall o di limitazione della frequenza lo rifiuta | Rileggere la regola: si rifiuta un robot che si vorrebbe vedere citare il sito |
| Un 200 su robots.txt e nient'altro | Il robot legge il robots.txt e non vi trova alcuna URL da esplorare, oppure tutto vi è vietato | Verificare il robots.txt token per token |
Un promemoria sui rifiuti: un 403 restituito dal server di origine compare nel log. Un 403 restituito dal CDN non vi compare, perché la richiesta non è mai arrivata. Un log senza alcun errore non è quindi la prova che nessuna richiesta venga rifiutata.
# il codice di risposta è il 9o campo del formato combined
awk '/GPTBot/ {print $9}' ia.log | sort | uniq -c | sort -rn
Fase 5: guardare quali pagine vengono lette
Molti editori si fermano prima di questa fase, che è però quella che insegna di più. Si contano, per ogni robot di ricerca e ogni agente utente, i percorsi richiesti, e li si confronta con l'elenco delle pagine pubblicate. Il conteggio risponde a domande che nessun altro strumento risolve:
- Quali pagine non vengono mai lette? Un articolo pubblicato da due mesi che nessun robot di ricerca ha richiesto probabilmente non è nella sitemap, o non è raggiungibile da un link.
- Quali pagine vengono lette dagli agenti utente? Sono quelle che gli assistenti citano davvero. Il confronto con le pagine che si vorrebbe vedere citate dice dove portare lo sforzo di scrittura.
- Il robot rilegge le pagine modificate? Se una pagina aggiornata la settimana scorsa non è stata richiesta di nuovo, il segnale di freschezza non passa. Abbiamo spiegato perché in «Una sitemap con date identiche non serve a nulla».
# i percorsi più letti dal robot di ricerca, 7o campo
awk '/OAI-SearchBot/ {print $7}' ia.log | sort | uniq -c | sort -rn | head -30
Fase 6: annotare la cadenza e rifare la misura
L'ultima lettura riguarda il tempo. Per ogni robot si rileva il numero di giorni di visita sul periodo, l'intervallo tra due passaggi e l'ora abituale. Un robot di ricerca che passa ogni giorno ha integrato il sito nel suo ciclo; un robot che è passato una volta per leggere tutto e poi è tornato solo sulla sitemap aspetta un segnale di cambiamento. Questa cadenza è il riferimento con cui si confronteranno le misure successive, una volta alla settimana o una volta al mese secondo il ritmo di pubblicazione.
Occorre anche conservare il file di lavoro. La durata di conservazione dipende dal provider di hosting e dal contratto, e si conta spesso in giorni più che in mesi: verificate la vostra prima di averne bisogno. Passato questo termine il dato non esiste più, e una domanda posta a dicembre su quello che è successo a settembre resterà senza risposta.
# giorni di visita, poi l ora abituale
awk '/GPTBot/ {print substr($4,2,11)}' ia.log | sort -u
awk '/GPTBot/ {print substr($4,14,2)}' ia.log | sort | uniq -c
I tre errori che si fanno quasi sempre la prima volta
Il primo è concludere su un campione: le ultime ore, la prima pagina di uno strumento, una sola giornata. Un robot può aver letto tutto il sito un martedì sera e non comparire più per otto giorni. Si guarda l'intero periodo prima di dire che non viene.
Il secondo è testare dalla propria postazione. Inviare una richiesta con lo user-agent di GPTBot da una rete d'ufficio e ricevere un 403 prova soltanto che gli impostori vengono rifiutati; il robot vero, invece, può passare. L'unico test che vale è il confronto tra quello che il log mostra per il robot autentico e quello che si ottiene di persona.
Il terzo è dimenticare ciò che non arriva fino al log. Un sito dietro un CDN che rifiuta i robot di IA avrà un access log perfettamente pulito e vuoto di ogni IA. La lettura dei log comincia dalla lettura della configurazione del CDN, e dai registri del CDN stesso quando sono accessibili.
Che cosa rende questa mezz'ora
Alla fine dell'esercizio un editore sa tre cose che nessuna dashboard gli darà: quali motori generativi indicizzano il suo sito, quali pagine leggono, e se persone reali vi arrivano tramite un assistente. È la base di ogni strategia di visibilità nelle IA, prima delle misure di share of voice che descriviamo in «Misurare la propria visibilità nelle IA». Una piattaforma editoriale può automatizzare questa lettura e mostrarla ogni giorno; ma la prima volta bisogna averla fatta a mano, per sapere che cosa si guarda.
Scritto da
Yann Léguillon
Presidente di Mazette, l'editore di Joornal. Accompagna le aziende che costruiscono la propria testata: strutturazione editoriale, visibilità nei motori di ricerca e nelle IA, produzione su larga scala.