Leer un access log en 30 minutos: lo que los robots de IA hacen de verdad en su sitio
Ningún panel le dice a un editor si ChatGPT, Claude o Perplexity leen sus páginas. Search Console solo cubre Google, y los motores generativos no facilitan nada. La única fuente que existe es el registro de peticiones del servidor, el access log, que todo alojamiento produce y que casi nadie abre. En media hora, con las herramientas presentes en cualquier servidor Linux, se lee ahí quién viene, para qué y qué le ha respondido el servidor. Este es el método que aplicamos, etapa por etapa, con los comandos. Reparto de la media hora: cinco minutos para la extracción, cinco para el recuento por robot, diez para la verificación de las direcciones, cinco para los códigos de respuesta, cinco para las rutas y la cadencia.
Todos los comandos que siguen suponen un registro en formato combinado y se ejecutan sobre el fichero extraído en la etapa 1. Solo usan grep, awk, sort y uniq.
Lo que contiene una línea
Un access log en formato combinado, el de Apache y nginx por defecto, contiene una línea por petición. Cada línea da, en este orden: la dirección IP del cliente, la fecha y la hora, el método y la ruta solicitados, el código de respuesta, el tamaño enviado, el referer y el user-agent. Para el análisis de los robots cuentan cuatro campos:
| Campo | Para qué sirve |
|---|---|
| Dirección IP | Verificar que el robot es quien dice ser |
| Ruta | Saber qué páginas se leen, y cuáles no se leen nunca |
| Código de respuesta | Saber si el robot ha obtenido la página, una redirección, un error o un rechazo |
| User-agent | Identificar la familia y el rol del robot |
Primera comprobación, antes de cualquier análisis: la dirección IP registrada, ¿es la del visitante o la de un intermediario? Tras un CDN o un proxy, el servidor ve la dirección del intermediario, salvo que esté configurado para leer la cabecera que transporta la dirección original. Si todas las peticiones parecen venir de unas pocas decenas de direcciones, la etapa de verificación descrita más abajo no será posible, y hay que corregir la configuración antes de seguir. Describimos esta trampa en «Lo que el cortafuegos oculta a sus logs».
Etapa 1: aislar el periodo y los robots de IA
Se trabaja sobre un periodo completo, siete días como mínimo, porque los robots de IA no pasan todos los días y las conclusiones sacadas de veinticuatro horas son casi siempre falsas. Después se extraen las líneas cuyo user-agent contiene uno de los tokens publicados por los proveedores: GPTBot, ChatGPT-User, OAI-SearchBot para OpenAI; ClaudeBot, Claude-User, Claude-SearchBot para Anthropic; PerplexityBot y Perplexity-User para Perplexity; Google-Extended no aparece en los logs, puesto que es un token de robots.txt y no un robot. Las listas de referencia son las de OpenAI, de Anthropic y de Perplexity.
Basta un filtro grep sobre esos tokens, redirigido a un fichero de trabajo. En un medio de tamaño mediano se obtienen de unos centenares a unos millares de líneas por semana.
zcat -f access.log* \
| grep -E 'GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User' \
> ia.log
Etapa 2: contar por robot y por rol
Cada proveedor explota varios robots que no hacen lo mismo, y esa es la distinción más útil de todo el análisis. Un robot de entrenamiento recoge páginas para futuros modelos. Un robot de búsqueda construye un índice para responder a las preguntas. Un robot bajo demanda va a buscar una página para una persona que pregunta al asistente. Hemos detallado los roles y los tokens en «robots.txt e IA».
Se cuentan, pues, las líneas por user-agent, y se agrupan en tres columnas: entrenamiento, búsqueda, agente de usuario. El resultado se lee así:
- Unas peticiones de entrenamiento a solas significan que el sitio se recoge, pero nada dice que se cite.
- Unas peticiones de búsqueda indican que el sitio está indexado por el motor generativo, condición necesaria para ser citado.
- Unas peticiones de agente de usuario son la señal más valiosa: cada una corresponde a la pregunta de un usuario para la que el asistente ha ido a buscar esa página.
grep -oE 'GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User' ia.log \
| sort | uniq -c | sort -rn
Etapa 3: verificar que los robots son auténticos
Un user-agent se declara libremente. Cualquier script puede presentarse como GPTBot. Antes de contar, se verifica que las direcciones IP pertenecen a los rangos publicados por cada proveedor: OpenAI, Anthropic y Perplexity publican ficheros de rangos, y Google documenta la verificación de sus robots mediante reverse DNS. Se extraen las direcciones distintas por user-agent, se comparan con los rangos y se descarta lo que no figura en ellos. El método completo, con sus trampas, está en «¿Es un robot quien dice ser?».
Las encontramos en la mayoría de los sitios que auditamos: peticiones que se declaran Googlebot o GPTBot desde direcciones que no pertenecen ni a Google ni a OpenAI. No tenemos una volumetría publicable que asociarles; la prueba, en cambio, cabe en un comando. Contar sin verificar es arriesgarse a medir scrapers disfrazados.
# las direcciones distintas de un robot, para confrontarlas con los rangos publicados
awk '/GPTBot/ {print $1}' ia.log | sort -u
Etapa 4: leer los códigos de respuesta
Para cada robot auténtico se desglosan los códigos de respuesta. La tabla esperada en un sitio sano es casi por completo de 200, con algunos 304 si el servidor gestiona las peticiones condicionales, y algunos 404 en URL retiradas. Tres anomalías merecen una acción:
| Observación | Causa probable | Acción |
|---|---|---|
| Muchos 301 o 302 | El robot sigue URL antiguas, o el sitemap declara direcciones no canónicas | Corregir el sitemap, declarar solo las URL finales |
| Algunos 403 o 429 para un robot auténtico | Una regla de cortafuegos o de limitación de velocidad lo rechaza | Releer la regla: se está rechazando a un robot al que se querría ver citar el sitio |
| Un 200 en robots.txt y nada más | El robot lee el robots.txt y no encuentra en él ninguna URL que recorrer, o todo está prohibido | Revisar el robots.txt token por token |
Un recordatorio sobre los rechazos: un 403 devuelto por el servidor de origen aparece en el log. Un 403 devuelto por el CDN no aparece, puesto que la petición nunca llegó. Un log sin ningún error no es, por tanto, la prueba de que no se rechaza ninguna petición.
# el código de respuesta es el 9.º campo del formato combinado
awk '/GPTBot/ {print $9}' ia.log | sort | uniq -c | sort -rn
Etapa 5: mirar qué páginas se leen
Muchos editores se detienen antes de esta etapa, que es sin embargo la que más enseña. Se cuentan, para cada robot de búsqueda y cada agente de usuario, las rutas solicitadas, y se comparan con la lista de páginas publicadas. El recuento responde a preguntas que ninguna otra herramienta resuelve:
- ¿Qué páginas no se leen nunca? Un artículo publicado hace dos meses que ningún robot de búsqueda ha solicitado probablemente no está en el sitemap, o no es alcanzable por un enlace.
- ¿Qué páginas leen los agentes de usuario? Son las que los asistentes citan de verdad. La comparación con las páginas que se querría ver citadas dice dónde poner el esfuerzo de escritura.
- ¿El robot relee las páginas modificadas? Si una página actualizada la semana pasada no se ha vuelto a solicitar, la señal de frescura no pasa. Hemos explicado por qué en «Un sitemap con fechas idénticas no sirve de nada».
# las rutas más leídas por el robot de búsqueda, 7.º campo
awk '/OAI-SearchBot/ {print $7}' ia.log | sort | uniq -c | sort -rn | head -30
Etapa 6: anotar la cadencia y repetir la medición
La última lectura recae sobre el tiempo. Para cada robot se anota el número de días de visita en el periodo, el intervalo entre dos pasadas y la hora habitual. Un robot de búsqueda que pasa cada día ha integrado el sitio en su ciclo; un robot que pasó una vez para leerlo todo y luego solo volvió al sitemap espera una señal de cambio. Esa cadencia es la referencia con la que se compararán las mediciones siguientes, una vez por semana o una vez al mes según el ritmo de publicación.
Hay que conservar además el fichero de trabajo. La duración de conservación depende del proveedor de alojamiento y del contrato, y suele contarse en días más que en meses: compruebe la suya antes de necesitarla. Pasado ese plazo, el dato ya no existe, y una pregunta formulada en diciembre sobre lo que ocurrió en septiembre se quedará sin respuesta.
# días de visita, luego la hora habitual
awk '/GPTBot/ {print substr($4,2,11)}' ia.log | sort -u
awk '/GPTBot/ {print substr($4,14,2)}' ia.log | sort | uniq -c
Los tres errores que casi siempre se cometen la primera vez
El primero es concluir sobre una muestra: las últimas horas, la primera página de una herramienta, un solo día. Un robot puede haber leído todo el sitio un martes por la noche y no volver a aparecer durante ocho días. Se mira el periodo entero antes de decir que no viene.
El segundo es hacer la prueba desde el propio puesto. Enviar una petición con el user-agent de GPTBot desde una red de oficina y recibir un 403 solo prueba que los suplantadores quedan rechazados; el robot auténtico sí puede pasar. La única prueba que vale es comparar lo que muestra el log para el robot auténtico con lo que se obtiene uno mismo.
El tercero es olvidar lo que no llega hasta el log. Un sitio tras un CDN que rechaza los robots de IA tendrá un access log perfectamente limpio y vacío de toda IA. La lectura de los logs empieza por la lectura de la configuración del CDN, y por los registros del propio CDN cuando son accesibles.
Lo que aporta esta media hora
Al terminar el ejercicio, un editor sabe tres cosas que ningún panel le dará: qué motores generativos indexan su sitio, qué páginas leen y si llegan personas reales a través de un asistente. Es la base de toda estrategia de visibilidad en las IA, antes de las mediciones de share of voice que describimos en «Medir la visibilidad en las IA». Una plataforma editorial puede automatizar esta lectura y mostrarla cada día; pero la primera vez hay que haberla hecho a mano, para saber qué se está mirando.
Escrito por
Yann Léguillon
Presidente de Mazette, la editora de Joornal. Acompaña a empresas que construyen su propio medio: estructuración editorial, visibilidad en los buscadores y en las IA, producción a escala.