Crawlers et logs

Lire un access log en 30 minutes : ce que les robots d'IA font vraiment sur votre site

Des bandes verticales orange irrégulières, certaines comme interrompues ou décalées, traversent un fond bleu-vert saturé avec une texture de trame et un fort grain, évoquant l’idée d’une séquence de requêtes analysées et marquées par des anomalies dans un

Aucun tableau de bord ne dit à un éditeur si ChatGPT, Claude ou Perplexity lisent ses pages. La Search Console ne couvre que Google, et les moteurs génératifs ne fournissent rien. La seule source qui existe est le journal des requêtes du serveur, l'access log, que tout hébergement produit et que presque personne n'ouvre. En une demi-heure, avec les outils présents sur n'importe quel serveur Linux, on y lit qui vient, pour quoi faire, et ce que le serveur lui a répondu. Voici la méthode que nous appliquons, étape par étape, avec les commandes. Le découpage de la demi-heure : cinq minutes pour l'extraction, cinq pour le comptage par robot, dix pour la vérification des adresses, cinq pour les codes de réponse, cinq pour les chemins et la cadence.

Toutes les commandes qui suivent supposent un journal au format combiné et se lancent sur le fichier extrait à l'étape 1. Elles n'utilisent que grep, awk, sort et uniq.

Ce que contient une ligne

Un access log au format combiné, celui d'Apache et de nginx par défaut, contient une ligne par requête. Chaque ligne donne, dans l'ordre : l'adresse IP du client, la date et l'heure, la méthode et le chemin demandés, le code de réponse, la taille envoyée, le referer et le user-agent. Pour l'analyse des robots, quatre champs comptent :

ChampCe qu'il permet
Adresse IPVérifier que le robot est bien celui qu'il prétend être
CheminSavoir quelles pages sont lues, et lesquelles ne le sont jamais
Code de réponseSavoir si le robot a obtenu la page, une redirection, une erreur ou un refus
User-agentIdentifier la famille et le rôle du robot

Première vérification, avant toute analyse : l'adresse IP enregistrée est-elle celle du visiteur, ou celle d'un intermédiaire ? Derrière un CDN ou un proxy, le serveur voit l'adresse de l'intermédiaire, sauf s'il est configuré pour lire l'en-tête qui transporte l'adresse d'origine. Si toutes les requêtes semblent venir de quelques dizaines d'adresses, l'étape de vérification décrite plus bas ne sera pas possible, et il faut corriger la configuration avant de continuer. Nous avons décrit ce piège dans « Ce que le pare-feu cache à vos logs ».

Grande grille de points blancs sur fond bleu marine, qui se densifie en quelques zones puis s’interrompt brusquement par des vides iréguliers marqués d’un accent orange, suggérant l’analyse de flux et la détection d’anomalies dans une séquence régulière.

Étape 1 : isoler la période et les robots d'IA

On travaille sur une période complète, sept jours au minimum, parce que les robots d'IA ne passent pas tous les jours et que les conclusions tirées de vingt-quatre heures sont presque toujours fausses. On extrait ensuite les lignes dont le user-agent contient l'un des tokens publiés par les fournisseurs : GPTBot, ChatGPT-User, OAI-SearchBot pour OpenAI ; ClaudeBot, Claude-User, Claude-SearchBot pour Anthropic ; PerplexityBot et Perplexity-User pour Perplexity ; Google-Extended n'apparaît pas dans les logs, puisque c'est un jeton de robots.txt et non un robot. Les listes de référence sont celles de OpenAI, d'Anthropic et de Perplexity.

Un filtre grep sur ces jetons, dirigé vers un fichier de travail, suffit. Sur un média de taille moyenne, on obtient de quelques centaines à quelques milliers de lignes par semaine.

zcat -f access.log* \
  | grep -E 'GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User' \
  > ia.log

Étape 2 : compter par robot et par rôle

Chaque fournisseur exploite plusieurs robots qui ne font pas la même chose, et c'est la distinction la plus utile de toute l'analyse. Un robot d'entraînement collecte des pages pour de futurs modèles. Un robot de recherche construit un index pour répondre aux questions. Un robot à la demande va chercher une page pour une personne qui pose une question à l'assistant. Nous avons détaillé les rôles et les jetons dans « robots.txt et IA ».

On compte donc les lignes par user-agent, et on les regroupe en trois colonnes : entraînement, recherche, agent utilisateur. Le résultat se lit ainsi :

  • Des requêtes d'entraînement seules signifient que le site est collecté, mais rien ne dit qu'il est cité.
  • Des requêtes de recherche indiquent que le site est indexé par le moteur génératif, condition nécessaire pour être cité.
  • Des requêtes d'agent utilisateur sont le signal le plus précieux : chacune correspond à une question d'utilisateur pour laquelle l'assistant est allé chercher cette page.
grep -oE 'GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User' ia.log \
  | sort | uniq -c | sort -rn

Étape 3 : vérifier que les robots sont authentiques

Un user-agent se déclare librement. N'importe quel script peut se présenter comme GPTBot. Avant de compter, on vérifie que les adresses IP appartiennent aux plages publiées par chaque fournisseur : OpenAI, Anthropic et Perplexity publient des fichiers de plages, et Google documente la vérification de ses robots par reverse DNS. On extrait les adresses distinctes par user-agent, on les compare aux plages, et on écarte ce qui n'y figure pas. La méthode complète, avec ses pièges, est dans « Un robot est-il bien celui qu'il prétend être ? ».

Nous en trouvons sur la plupart des sites que nous auditons : des requêtes qui se déclarent Googlebot ou GPTBot depuis des adresses qui n'appartiennent ni à Google ni à OpenAI. Nous n'avons pas de volumétrie publiable à y associer ; le test, lui, tient en une commande. Compter sans vérifier, c'est risquer de mesurer des scrapers déguisés.

# les adresses distinctes d un robot, a confronter aux plages publiees
awk '/GPTBot/ {print $1}' ia.log | sort -u

Étape 4 : lire les codes de réponse

Pour chaque robot authentique, on ventile les codes de réponse. Le tableau attendu sur un site sain est presque entièrement en 200, avec quelques 304 si le serveur gère les requêtes conditionnelles, et quelques 404 sur des URL retirées. Trois anomalies méritent une action :

ObservationCause probableAction
Beaucoup de 301 ou 302Le robot suit d'anciennes URLs, ou le sitemap déclare des adresses non canoniquesCorriger le sitemap, ne déclarer que les URLs finales
Des 403 ou 429 pour un robot authentiqueUne règle de pare-feu ou de limitation de débit le refuseRelire la règle : on refuse un robot qu'on voudrait voir citer le site
Un 200 sur robots.txt et rien d'autreLe robot lit le robots.txt et n'y trouve aucune URL à explorer, ou tout y est interditVérifier le robots.txt jeton par jeton

Un rappel sur les refus : un 403 renvoyé par le serveur d'origine apparaît dans le log. Un 403 renvoyé par le CDN n'y apparaît pas, puisque la requête n'est jamais arrivée. Un log sans aucune erreur n'est donc pas la preuve qu'aucune requête n'est refusée.

Des bandes parallèles horizontales, régulièrement espacées sur fond bleu nuit, sont interrompues à quelques endroits, suggérant des irrégularités ou des anomalies dans un flux structuré.
# le code de reponse est le 9e champ du format combine
awk '/GPTBot/ {print $9}' ia.log | sort | uniq -c | sort -rn

Étape 5 : regarder quelles pages sont lues

Beaucoup d'éditeurs s'arrêtent avant cette étape, qui est pourtant celle qui apprend le plus. On compte, pour chaque robot de recherche et chaque agent utilisateur, les chemins demandés, et on les compare à la liste des pages publiées. Le comptage répond à des questions qu'aucun autre outil ne tranche :

  1. Quelles pages ne sont jamais lues ? Un article publié depuis deux mois qu'aucun robot de recherche n'a demandé n'est probablement pas dans le sitemap, ou pas atteignable par un lien.
  2. Quelles pages sont lues par les agents utilisateurs ? Ce sont celles que les assistants citent réellement. La comparaison avec les pages qu'on voudrait voir citées dit où porter l'effort d'écriture.
  3. Le robot relit-il les pages modifiées ? Si une page mise à jour la semaine dernière n'a pas été redemandée, le signal de fraîcheur ne passe pas. Nous avons expliqué pourquoi dans « Un sitemap avec des dates identiques ne sert à rien ».
# les chemins les plus lus par le robot de recherche, 7e champ
awk '/OAI-SearchBot/ {print $7}' ia.log | sort | uniq -c | sort -rn | head -30

Étape 6 : noter la cadence et refaire la mesure

La dernière lecture porte sur le temps. Pour chaque robot, on relève le nombre de jours de visite sur la période, l'intervalle entre deux passages, et l'heure habituelle. Un robot de recherche qui passe chaque jour a intégré le site dans son cycle ; un robot qui est passé une fois pour tout lire puis n'est revenu que sur le sitemap attend un signal de changement. Cette cadence est la référence à laquelle on comparera les mesures suivantes, une fois par semaine ou une fois par mois selon le rythme de publication.

Il faut aussi conserver le fichier de travail. La durée de conservation dépend de l'hébergeur et du contrat, et elle se compte souvent en jours plutôt qu'en mois : vérifiez la vôtre avant d'en avoir besoin. Passé ce délai, la donnée n'existe plus, et une question posée en décembre sur ce qui s'est passé en septembre restera sans réponse.

# jours de visite, puis heure habituelle
awk '/GPTBot/ {print substr($4,2,11)}' ia.log | sort -u
awk '/GPTBot/ {print substr($4,14,2)}' ia.log | sort | uniq -c

Les trois erreurs qu'on fait presque toujours la première fois

La première est de conclure sur un échantillon : les dernières heures, la première page d'un outil, une seule journée. Un robot peut avoir lu tout le site un mardi soir et ne plus apparaître pendant huit jours. On regarde la période entière avant de dire qu'il ne vient pas.

La deuxième est de tester depuis son propre poste. Envoyer une requête avec le user-agent de GPTBot depuis un réseau de bureau et recevoir un 403 prouve seulement que les usurpateurs sont refusés ; le vrai robot, lui, peut passer. Le seul test qui vaut est la comparaison entre ce que le log montre pour le robot authentique et ce qu'on obtient soi-même.

La troisième est d'oublier ce qui n'arrive pas jusqu'au log. Un site derrière un CDN qui refuse les robots d'IA aura un access log parfaitement propre et vide de toute IA. La lecture des logs commence par la lecture de la configuration du CDN, et par les journaux du CDN lui-même quand ils sont accessibles.

Ce que cette demi-heure rapporte

À la fin de l'exercice, un éditeur sait trois choses qu'aucun tableau de bord ne lui donnera : quels moteurs génératifs indexent son site, quelles pages ils lisent, et si des personnes réelles y arrivent par un assistant. C'est la base de toute stratégie de visibilité dans les IA, avant les mesures de part de voix que nous décrivons dans « Mesurer sa visibilité dans les IA ». Une plateforme éditoriale peut automatiser cette lecture et l'afficher chaque jour ; mais la première fois, il faut l'avoir faite à la main, pour savoir ce qu'on regarde.

Des arcs concentriques en points de trame se superposent sur fond bleu nuit, créant un motif central qui évoque des couches d'information rendues visibles, dans une texture granuleuse d'impression.
Yann Léguillon, président de Mazette

Écrit par

Yann Léguillon

Président de Mazette, l'éditeur de Joornal. Il accompagne des entreprises qui construisent leur média : structuration éditoriale, visibilité dans les moteurs et dans les IA, production à l'échelle.