Nuestro interés, sin rodeos: somos Geonode y vendemos proxies, y las preguntas sobre el agente de usuario suelen llegar acompañadas de «¿por qué me bloquean?». La respuesta sincera es que el agente de usuario es una de las señales menos fiables que existen, y que incluir una cadena de navegador en una solicitud cuya huella TLS indique lo contrario es peor que no disimular nada en absoluto: has creado una incoherencia que un navegador real nunca produciría. Más abajo hay una sección dedicada a esto. La estrategia que funciona con más frecuencia de lo que la gente espera es justo la contraria: di quién eres, proporciona una URL de contacto y compórtate de forma razonable. La automatización anónima se bloquea con mucha más facilidad que la identificada, y identificarte es gratis.
La sintaxis
curl -A "MyBot/1.0" https://example.com
El manual de curl describe -A, --user-agent <name>
: «Especifica la cadena User-Agent que se enviará al servidor HTTP. Para codificar los espacios en blanco de la cadena, rodéala de comillas simples o dobles».
También se indica el valor por defecto: «Por defecto, curl utiliza curl/VERSION
, como por ejemplo User-Agent: curl/8.22.0
».
Así pues, sin ninguna opción, cada solicitud que realices se identifica como curl y su versión. Algunos servidores responden de forma diferente en función de ello, lo cual conviene saber antes de concluir que un sitio web no funciona.
El equivalente utilizando un encabezado genérico:
curl -H "User-Agent: MyBot/1.0" https://example.com
Ambas opciones producen el mismo resultado: el manual señala que el encabezado «también se puede configurar con las opciones --header
o --proxy-header
». -A
es más breve; -H
es coherente con la forma en que se configuran todos los demás encabezados, lo cual es importante si se generan comandos mediante programación.
Si se especifica varias veces, «se utiliza el último valor establecido».
Eliminar el encabezado por completo
Hay un caso que mucha gente desconoce, y el manual es muy claro al respecto:
Si se pasa un argumento vacío a
--user-agent(«»), se elimina por completo el encabezado de la solicitud. Si se prefiere un encabezado en blanco, se puede establecer como un solo espacio (« »).
curl -A "" https://example.com # no User-Agent header at all
curl -A " " https://example.com # User-Agent: (empty value)
Se trata de solicitudes realmente diferentes. No enviar ningún encabezado no es lo mismo que enviar uno vacío, y los servidores pueden distinguirlos.
Ambas situaciones son inusuales, y lo inusual es en sí mismo una señal. Una solicitud sin ningún agente de usuario es más rara que una que se identifique como curl, por lo que eliminar el encabezado para parecer menos llamativo suele conseguir lo contrario.
El mismo mecanismo funciona a través de -H, y el manual explica la sintaxis para ambos casos: «Elimina un encabezado interno indicando un sustituto sin contenido a la derecha de los dos puntos, como en: -H "Host:"», mientras que un encabezado con un valor vacío necesita un punto y coma — -H "X-Custom-Header;" envía X-Custom-Header:.
Por qué es importante el valor por defecto «
curl/8.22.0» es una cadena perfectamente válida, y eso tiene consecuencias.
Algunos servidores la bloquean directamente. Es fácil escribir una regla general contra las herramientas de automatización conocidas, y es tan habitual que te la encontrarás.
Otros muestran un contenido diferente. Un marcado simplificado, sin secciones que dependan de JavaScript y, en ocasiones, una página totalmente distinta.
Otros lo registran y no hacen nada. Este es, con diferencia, el caso más habitual.
Algunas CDN lo tratan como una señal más entre muchas, en lugar de como un criterio decisivo por sí solo.
La consecuencia práctica es que la afirmación «funciona en mi navegador, pero no en curl» tiene varias causas posibles, y el agente de usuario es solo una de ellas. Antes de cambiarlo, comprueba si la diferencia se debe realmente a JavaScript: «curl» no lo ejecuta, por lo que una página generada en el lado del cliente parecerá casi vacía para «curl», independientemente del encabezado que envíes. No se trata de un problema que impida el funcionamiento y ningún agente de usuario lo soluciona.
Qué enviar en su lugar
En el caso de los clientes automatizados, la cadena que menos se bloquea es aquella que indica qué eres.
curl -A "AcmePriceBot/1.2 (+https://acme.example.com/bot)" https://example.com
La convención consta de tres partes: un nombre, una versión y una URL donde se pueda averiguar qué eres y cómo contactar contigo. Funciona porque ofrece al administrador del sitio opciones distintas al bloqueo. Un patrón de solicitudes sin explicar es un problema que hay que detener; un rastreador identificado con una página de contacto es una decisión que hay que tomar, y con frecuencia la decisión es permitirlo.
Tres ventajas prácticas, todas reales:
**robots.txt
puede dirigirse a ti específicamente.** Las reglas se comparan mediante el token del agente de usuario, por lo que un sitio web puede conceder a tu rastreador un permiso que no concede a todo el mundo. Eso no puede suceder si eres anónimo.
Los operadores pueden ponerse en contacto contigo antes de bloquearte. Esto ocurre con más frecuencia de lo que la gente espera, y es un resultado mucho mejor que descubrir un bloqueo tres semanas después.
Permite solicitar acceso. «Somos el rastreador identificado como AcmePriceBot; esto es lo que hacemos» es una conversación que puede llevar a algo. «Somos un script no identificado» no lo es.
Acompáñalo con un comportamiento acorde con lo que afirmas: respeta robots.txt
, Crawl-delay
y Retry-After
, mantén una frecuencia de acceso moderada y utiliza el caché para no recuperar nunca dos veces el mismo recurso sin cambios.
Configurarlo de forma coherente en los scripts
Para cualquier cosa que vaya más allá de un solo comando, coloca la cadena en un solo lugar.
UA="AcmePriceBot/1.2 (+https://acme.example.com/bot)"
curl -sS --fail --location \
--user-agent "$UA" \
--connect-timeout 5 --max-time 30 \
"$URL"
O configúralo una sola vez en un archivo de configuración de curl, lo que garantiza la coherencia en cada ejecución sin tener que repetir el parámetro:
# bot.conf
--user-agent "AcmePriceBot/1.2 (+https://acme.example.com/bot)"
--location
--show-error
curl -K bot.conf "$URL"
Una advertencia específica sobre ~/.curlrc
: se aplica a todas las ejecuciones de curl de ese usuario, incluidos los comandos que no hayas escrito tú. Establecer allí un agente de usuario de bot significa que cada solicitud ad hoc que realices se identificará como tu rastreador, lo que generará resultados confusos meses más tarde. Utiliza un archivo de configuración con nombre en -K
para cualquier aspecto específico de la carga de trabajo.
Si necesitas varios agentes de usuario en una misma carga de trabajo, guárdalos en una matriz y selecciónalos de forma deliberada en lugar de al azar: la rotación aleatoria dentro de una sesión da lugar a un cliente que parece cambiar de navegador a mitad de la visita, lo cual es otra inconsistencia en lugar de un camuflaje.
Comprobar lo que realmente has enviado
Es un hábito que vale la pena adquirir, ya que las suposiciones sobre los encabezados suelen ser erróneas con sorprendente frecuencia.
curl -v -A "MyBot/1.0" https://example.com 2>&1 | grep -i '^> user-agent'
La salida detallada se envía a stderr, de ahí el comando «2>&1». Las líneas «>» son lo que curl ha transmitido.
O bien, pide a un servicio que te lo devuelva:
curl -sS -A "MyBot/1.0" https://httpbin.org/user-agent
Esto es más importante de lo que parece debido a un comportamiento específico que describe el manual: «si añades un encabezado personalizado que tiene el mismo nombre que uno de los internos que utilizaría curl, se utilizará tu encabezado establecido externamente en lugar del interno». Así pues, combinar -A con -H "User-Agent: ..." significa que uno de ellos prevalece de forma silenciosa, y saber cuál requiere comprobarlo. Vale la pena repetir el propio consejo del manual: «No debes sustituir los encabezados establecidos internamente sin saber perfectamente lo que estás haciendo».
La misma comprobación se aplica a través de un proxy, donde --proxy-header establece los encabezados en la conexión del proxy en lugar de en la solicitud de destino —una distinción que confunde a los usuarios cuando un encabezado que han establecido parece no llegar—.
Cómo leer una cadena de User-Agent
Merece la pena entenderlo, tanto porque quizá tengas que crear una como porque el formato explica por qué las cadenas de los navegadores tienen un aspecto tan extraño.
Una cadena moderna de Chrome tiene más o menos este aspecto:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Casi nada de eso es cierto. No es Mozilla, no es Safari, y AppleWebKit/537.36 lleva años sin actualizarse. La cadena es un registro fósil de dos décadas de negociación de contenido: cada navegador añadía los tokens de sus predecesores para que los servidores que detectaran a un competidor le sirvieran la versión adecuada de la página. El resultado es un formato que casi no contiene información fiable y que, sin embargo, es analizado por una gran cantidad de software.
La gramática estructural subyacente es sencilla: una secuencia de tokens de tipo «Product/Version», cada uno de ellos seguido opcionalmente de un comentario entre paréntesis. Esa es toda la especificación, y es la razón por la que una cadena como AcmePriceBot/1.2 (+https://acme.example.com/bot) está bien formada: un token de producto, una versión y un comentario que contiene una URL. El prefijo + en la URL es una convención más que un requisito, y goza de amplio reconocimiento.
La cuestión de los dispositivos móviles. Muchos sitios web ofrecen un marcado diferente a los clientes móviles, y el token distintivo suele ser Mobile en algún punto de la cadena. Si estás comprobando legítimamente cómo se muestra una página a los visitantes móviles, enviar un agente de usuario móvil es una negociación de contenido habitual, más que una suplantación de identidad —aunque se aplica la misma advertencia de siempre: una cadena «mobile» en una conexión de tipo ordenador de sobremesa con una ventana gráfica de ordenador de sobremesa es solo una afirmación a medias, y un navegador móvil real diferiría en varios otros aspectos.
Y la tendencia a la «congelación de versiones». Los navegadores han ido reduciendo progresivamente el nivel de detalle que exponen en este encabezado, trasladando la información sobre capacidades a indicaciones estructuradas del cliente. La implicación práctica es que el análisis del agente de usuario es una fuente de información cada vez menos relevante para todos —incluidos los sitios web que deciden cómo gestionar tus solicitudes—, lo cual constituye otra razón por la que es una señal débil sobre la que basar una estrategia.
Cuando el agente de usuario no es el problema
Casos en los que cambiarlo no servirá de nada, que se enumeran porque es lo primero que se suele intentar.
Cuando el contenido se genera mediante JavaScript. curl no ejecuta scripts. Una respuesta casi vacía significa que la página se genera en el lado del cliente, y la solución está en el navegador o en la API subyacente, no en un encabezado.
Cuando se aplica una limitación de frecuencia. Un «429» tiene que ver con el volumen, no con la identidad. Reducir la velocidad ayuda; un nuevo agente de usuario, no.
Cuando el problema es la dirección. Si se bloquea un rango completo, todas las solicitudes procedentes de él fallarán, independientemente de los encabezados.
Cuando se requiere autenticación. Un 401 solicita credenciales.
Cuando la huella digital de TLS te delata. Ya se ha tratado anteriormente, y es la razón por la que la suplantación de identidad del navegador solo mediante encabezados suele resultar decepcionante.
Cuando el sitio, sencillamente, no quiere tráfico automatizado. Algunos sitios lo indican en sus condiciones de uso y lo hacen cumplir. Cambiar un encabezado no modifica las condiciones, y un sitio que te ha dicho que no lo rastrees te ha dado información, no un acertijo.
El diagnóstico que permite distinguir rápidamente estos casos: solicita la misma URL desde un navegador normal utilizando la misma conexión. Si el navegador funciona y curl no, compara las dos solicitudes encabezado por encabezado; y si la única diferencia relevante resulta ser algo que no puedes cambiar desde la línea de comandos, ahí tienes la respuesta.
Preguntas frecuentes
¿Cómo configuro un User-Agent en curl?
curl -A "MyBot/1.0" URL, o de forma equivalente curl -H "User-Agent: MyBot/1.0" URL. Pon entre comillas la cadena si contiene espacios. Si se especifica más de una vez, prevalece el último valor.
¿Cuál es el User-Agent predeterminado de curl?
curl/VERSION — por ejemplo, curl/8.22.0. Se envía en cada solicitud a menos que lo sobrescribas o lo elimines, y algunos servidores responden de forma diferente en función de él.
¿Cómo elimino el encabezado User-Agent en curl?
curl -A "" URL elimina el encabezado por completo. curl -A " " URL lo envía con un valor vacío, lo que supone una solicitud diferente. Ten en cuenta que no enviar ningún agente de usuario es más inusual que enviar el predeterminado de curl, por lo que llama más la atención en lugar de menos.
¿Debería falsificar el User-Agent de un navegador con curl?
Normalmente no. Una cadena de navegador en una solicitud cuya huella digital TLS, conjunto de encabezados y orden sean todos de curl es una incoherencia que los navegadores reales nunca producen, lo que te hace más identificable en lugar de menos. Si necesitas solicitudes con apariencia de navegador, utiliza un navegador.
¿Cambiar el User-Agent evitará que me bloqueen?
Rara vez por sí solo. Ayuda frente a reglas generales que rechazan herramientas conocidas, pero no sirve de nada contra los límites de frecuencia, los bloqueos basados en direcciones, las huellas digitales de TLS o el análisis de comportamiento. Identificarse honestamente con una URL de contacto suele funcionar mejor que disfrazarse.
¿Cómo debería ser el User-Agent de un bot?
Nombre, versión y una URL de contacto: AcmePriceBot/1.2 (+https://acme.example.com/bot). Esto permite que robots.txt se dirija a ti específicamente, que los operadores se pongan en contacto contigo en lugar de bloquearte y te da legitimidad para solicitar acceso.
¿Puedo establecer un User-Agent diferente para cada solicitud?
Sí: -A se aplica a la invocación, así que proporciona un valor diferente cada vez, o utiliza --next para ejecutar varias operaciones con diferentes opciones en un solo comando. Evita rotar aleatoriamente dentro de una misma sesión, ya que esto hace que el cliente parezca cambiar de navegador a mitad de la visita.
¿Por qué no aparece mi User-Agent personalizado?
Lo más probable es que lo hayas configurado dos veces por medios diferentes, ya que curl utiliza el encabezado configurado externamente en lugar del interno, y prevalece la última definición. Compruébalo en curl -v ... 2>&1 | grep -i '^> user-agent' para ver qué se transmitió realmente.
Conclusión
Configurar un agente de usuario en curl es una opción, y la elección del valor es más importante que la sintaxis.
El valor por defecto identifica a curl con sinceridad, y la sinceridad es una postura defendible: coherente, discreta y, en ocasiones, la razón por la que un sitio web te trata de forma razonable. Es posible eliminar el encabezado —un argumento vacío lo suprime por completo, un solo espacio lo deja en blanco— y ambas opciones son menos habituales que el valor por defecto, lo cual es justo lo contrario de lo que la gente suele pretender.
Copiar una cadena de navegador es el instinto habitual y la opción más débil, porque esa afirmación se puede comprobar. Las huellas digitales de TLS, la composición y el orden de los encabezados, y el hecho de si se recogen los subrecursos de la página lo contradicen todo, y una contradicción es más fácil de identificar que una simple admisión. Si realmente se necesitan peticiones que parezcan procedentes de un navegador, la herramienta adecuada es un navegador.
El enfoque que funciona mejor de lo que la mayoría de la gente espera no cuesta nada: un nombre, una versión y una URL donde alguien pueda averiguar quién eres. Permite que robots.txt se dirija a ti, que un operador te envíe un correo electrónico en lugar de bloquearte, y convierte el «tráfico inexplicable» en «un rastreador con un propietario», lo cual es una posición mucho mejor en la que estar cuando alguien está decidiendo qué hacer contigo.
