PHP: Como determinar si es un visitante o es un robot www (boot)

Sencillo script que permite determinar si un visitante es ó no un robot. Estoy por publicar algo sobre un nuevo tema y me encontré con este tema de los robots WWW. Me di a la tarea de investigar sobre como diferenciar a una persona que visita la pagina o a un programa de esos que andan explorando la red buscando nuevos contenidos. Antes de iniciar con el ejemplo es necesario tener bien claro dos terminos: Robot y Agente.

¿Que es un robot WWW?

Un robot WWW es un programa que recorre periodicamente la estructura de internet en busca de nuevos contenidos. La forma de operar de estos programas por lo general es recuperando un documento raiz y de manera recursiva recorrer todos los documentos a los éste que hace referencia. El orden en que estos programas hacen el recorrido por lo general es determinado despues de hacer un analisis en base a varios parametros, es decir, despues de haber aplicado tecnicas de heurística. Estos programas a veces son llamados boots www, Robots web, Web Wanderers, Web Crawlers, o Spiders (arañas). Como ves, estos nombres son un poco engañosos ya que dan la impresion de que son un software parecido a los virus ya que se mueven en la internet rastreando entre los miles de sitios web. Si embargo, estos scripts/programas por lo general andan en busca de nuevos contenidos o información para fines estadísticos.

Imaginemos que un robot (por ejemplo el robot www de Google) anda explorando la red y se encuentra con nuestro sitio web y empieza a rastrear toda la estructura de documentos que hemos creado, si estamos guardando el tracking del sitio web ¿Debemos guardar el tracking de un robot www? ¿Debemos permitirle al robot explorar nuestro sitio?. En mi opinión, para mi sitio web la respuesta para ambas preguntas es SI.

Para la primer pregunta es es si porque asi llevo el seguimiento de cuantos robots y con que frecuencia visitan mi sitio web. El tracking entre mas detallado sea, mejor. La segunda pregunta tambien me conviene ya que muy probablemente que ese robot este recabando información acerca de que tan activo es mi sitio para asi posicionarlo o reclasificarlo mejor dentro de los indices de Google ¿porque habria de desagradarme que mi sitio web apareciera entre los primeros resultados de las busquedas de Google?. Hasta la pregunta suena comica ¿no?.

En la red internet existen varios sitios web que ofrecen de manera gratuita información gratuita y muy detallada acerca de los diferentes robots www mas conocidos. Estuve buscando por varios lugares y al final opte por elegir http://www.robotstxt.org/ pues contiene un listado de los boots www mas conocidos, este listado esta en el archivo http://www.robotstxt.org/db/all.txt. Lo que me gusto es que la lista esta muy extensa y detallada. Si gustas puedes abrir la URL ahora y podras ver que el detalle de cada robot es similar a la siguiente (robot www de Google):

robot-id: googlebot
robot-name: Googlebot
robot-cover-url: http://www.googlebot.com/ 
robot-details-url: http://www.googlebot.com/bot.html
robot-owner-name: Google Inc.
robot-owner-url: http://www.google.com/
robot-owner-email: googlebot@google.com 
robot-status: active
robot-purpose: indexing
robot-type: standalone 
robot-platform: Linux
robot-availability: none
robot-exclusion: yes
robot-exclusion-useragent: googlebot
robot-noindex: yes
robot-host: googlebot.com
robot-from: yes 
robot-useragent: Googlebot/2.X (+http://www.googlebot.com/bot.html)
robot-language: c++
robot-description: Google's crawler
robot-history: Developed by Google Inc
robot-environment: commercial
modified-date: Thu Mar 29 21:00:07 PST 2001
modified-by: googlebot@google.com

¿Que es Agente?

En informatica este termino se usa en muchisimos contextos pero en general podemos distinguir facilmente a los Agentes autonomos, los agentes inteligentes y a los agentes de usuario (User-agent). En este caso estamos interesados en los agentes de usuario, los cuales son programas que realizan tareas de red para un usuario.

Ejemplos de agentes de este tipo son los programas de navegacion (Mozilla Firefox, Netscape Navigator, Microsoft Internet Explorer, Google Chrome, Safari, etc) ó los clientes de correo electronico (Mozilla Thunderbird, Microsoft Outlook, etc).

Como hacer la distincion de un boot www

La forma de detectar al tipo de visitante es por medio del nombre del agente que accede a nuestro sitio. En PHP existe la variable global $_SERVER[‘HTTP_USER_AGENT’] que nos devuelve una cadena que indica el agente de usuario empleado para acceder a la pagina. A continuacion muestro el contenido que devuelve esta variable en varios navegadores (con ayuda de phpinfo()):

Google Chrome v. 22.0.1229.94 m
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
Firefox v. 13.0.1
Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1
Internet Explorer v. 8.0.7600.16385
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Safari v. 5.1.7 (7534.57.2)
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2

Implícitamente usaremos la información de esta variable para detectar a un robot www.

El codigo fuente para detectar robots www

Para hacer la distincion del agente que esta visitando nuestro sitio web aprovecharemos el listado de nombres de boots que mencione anteriormente: http://www.robotstxt.org/db/all.txt.

Basicamente leeremos ese archivo de texto desde un script PHP linea a linea y guardaremos el nombre de cada robot en un arreglo.
Despues compararemos cada item del arreglo contra el nombre del agente de usuario que esta visitando la pagina (valor que esta en la variable global $_SERVER[‘HTTP_USER_AGENT’]). Obviamente el visitante es un robot si el nombre del agente coincide con el nombre de algún robot del arreglo. A continuacion muestro el codigo:

<?php
/*
	Descripcion: Contiene una funcion que determina si el visitante es un robot www.
	Para esto hace uso del sitio http://www.robotstxt.org/db/all.txt
	que contiene un listado de los robots mas conocidos.
	Author: Gonzalo Silverio  gonzasilve@gmail.com
*/

/*
Parametros: El nombre de un agente de usuario.
Devuelve: true en caso de que el nombre del agente sea un nombre de robot
					false si el agente NO es un robot.
*/
	function esRobot($agente) {
		$archivoRobots = "http://www.robotstxt.org/db/all.txt";
		$delimitador1 = "robot-name:";
		$delimitador2 = ":";
		if (trim($agente)=="") $agente=trim($_GET['agente']);
		if (trim($agente)=="") $agente=trim($_SERVER['HTTP_USER_AGENT']);
		
		//Obtener el contenido del archivo como un array en donde cada item es una linea del archivo.
		$str_archivo = @file($archivoRobots);
		$total_lineas = count($str_archivo);

    $i = 0;
		$r = 0;
		$lista_robots = array();
		
    while ($i<=$total_lineas)    {
      $linea = chop($str_archivo[$i]);
			if(   (strpos($linea, $delimitador1) !== false) ) {
				$items= explode($delimitador2,$linea);
				$lista_robots[$r] = trim($items[1]);
				$r++;
			}
      $i++;
    }

		//Determina si la cadena que llega es un robot
		foreach($lista_robots as $robot)	{
			if(strpos($agente, trim($robot) )  !== false)
			return true;
		}
		return false;

	}

	//Ejemplos de como usar la funcion anterior:
	//Sintaxis 1
	if( esRobot("Pioneer") ) echo "SI"; else echo "NO";
	echo "<br/>";
	
	if( esRobot() ) echo "SI"; else echo "NO";
	echo "<br/>";	
	
	if( esRobot( trim($_SERVER['HTTP_USER_AGENT']) ) ) echo "SI"; else echo "NO";

?>

Si tienes duda acerca de como se usan algunas funciones de php te aconsejo que visites la pagina oficial de documentacion de PHP.
Al ejecutar el código anterior debes ver algo como:

SI
NO
NO

Si eres observador te darás cuenta que la ejecucion tarda un tiempo considerable ya que tiene que leer todo un archivo que esta en linea y debe parsearlo por completo y ademas depende de un sitio; si dicho sitio borra el archivo con los nombres de robots o le cambia de nombre o el formato en como estan organizados entonces la funcion anterior dejara de funcionar de manera correcta. Para solucionar esto vamos a bajar una copia del archivo y guardar unicamente los nombres de los robots, en cada linea estara el nombre de un robot y un delimitador, algo asi:

ABCdatos BotLink|#|
Acme.Spider|#|
Ahoy! The Homepage Finder|#|
Alkaline|#|
Anthill|#|
Walhello appie|#|
Arachnophilia|#|
Arale|#|
Araneo|#|
AraybOt|#|
ArchitextSpider|#|
..
... etc.

En este caso el delimitador es |#| y no una coma (,) ya que es posible que el nombre de un robot tenga ese caracter.

A continuación pongo otra versión del script para detectar robots pero ahora lee un archivo de texto local que tiene la sintaxis mencionada anteriormente:

<?php
/*
	Descripcion: Contiene una funcion que determina si el visitante es un robot www.
	Para esto hace uso del archivo local archivos/listaRobots.txt
	que contiene un listado de los robots mas conocidos.
	Author: Gonzalo Silverio  gonzasilve@gmail.com
 */

/*
	Parametros: El nombre de un agente de usuario.
	Devuelve: true en caso de que el nombre del agente sea un nombre de robot
	false si el agente NO es un robot.
 */
	function esRobot($agente) {
		$delimitador = "|#|";
		$archivoRobots = "archivos/listaRobots.txt";
		if (trim($agente)=="") $agente=trim($_GET['agente']);
		if (trim($agente)=="") $agente=trim($_SERVER['HTTP_USER_AGENT']);

		//Obtener el contenido del archivo como una cadena.
		$str_archivo = file_get_contents($archivoRobots,FILE_USE_INCLUDE_PATH);
		//Convertir cadena a arreglo con ayuda del delimitador
		$lista_robots = explode($delimitador,$str_archivo);

		foreach($lista_robots as $robot)	{
			if(strpos($agente, trim($robot) )  !== false)
				return true;
		}
		return false;
	}

	//Ejemplos de como usar la funcion anterior:
	//Sintaxis 1
	if( esRobot("Pioneer") ) echo "SI"; else echo "NO";
	echo "<br/>";

	if( esRobot() ) echo "SI"; else echo "NO";
	echo "<br/>";	

	if( esRobot( trim($_SERVER['HTTP_USER_AGENT']) ) ) echo "SI"; else echo "NO";

?>

Que facil ¿no?. Este dato podrias guardarlo en la base de datos para llevar un conteo de los robots que visitan tu sitio web. El resultado debe ser similar al anterior:

SI
NO
NO

 

Eso es todo. Si deseas el código basta con que dejes tu e-mail y en cuanto vea tu mensaje te hago llegar el ejemplo. Si te gusto el articulo, te invito a que me dejes un comentario, pero sobre todo a que me sigas visitando.

Saludos cordiales.