Parsear el robots.txt con PHP

Cuando construyes un robots de Internet has de tener en cuenta dos elementos:

  • Tener tu propio “User-Agent”
  • Cumplir el estándar de robots.txt

Para el primer elemento hay una forma muy sencilla de ejecutar un código en PHP:

ini_set("user_agent", "Agente 1.0 ");

Con esto ya consigues que, cuando se haya una petición desde PHP hacia cualquier sitio, en vez de llevar el agente del propio PHP se genere uno con los datos que tú indiques.

Aunque, quizá lo más interesante es tener un sistema de parseo de los ficheros de robots.txt. Para ello hemos de leer todas las líneas del fichero y procesarlas, sobretodo si coinciden con nuestro agente.

La idea es crear una función que consulte si tenemos acceso o no a esa dirección URL. Se puede mejorar con un sistema de caché y similar, pero lo pondré sencillo para dar unos primeros pasos.

function robots($url, $useragent=false) {
 
  // leemos la URL a revisar y sacamos la info
  $parseado = parse_url($url);
 
  // creamos un array de agentes posibles, incluyendo siempre el *
  $agentes = array(preg_quote('*'));
 
  // Si enviamos unos agentes por parámetro los revisamos
  // los agentes se pueden pasar por parámetro separados por "pipelines"
  if($useragent) $agentes[] = preg_quote($useragent);
  $agentes = implode('|', $agentes);
 
  // leemos el fichero robots.txt
  $robotstxt = @file("http://{$parsed['host']}/robots.txt");
  // y si no existe, se acabó todo
  if(!$robotstxt) return true;
 
  $reglas = array();
  $aplicadas = false;
  foreach($robotstxt as $linea) {
    if(!$linea = trim($linea)) continue;
 
    // Comprobamos si la línea hace referencia a un Agente
    if(preg_match('/User-agent:(.*)/i', $linea, $coincidencia)) {
      $aplicadas = preg_match("/($agentes)/i", $coincidencia[1]);
    }
 
    // Comprobamos si la línea hace referencia a una Regla
    if($aplicadas && preg_match('/Disallow:(.*)/i', $linea, $registro)) {
      if(!$registro[1]) return true;
      $reglas[] = preg_quote(trim($registro[1]), '/');
    }
  }
 
  // Comprobamos cada una de las reglas para la dirección que estamos revisando
  foreach($reglas as $regla) {
    if(preg_match("/^$regla/", $parseado['path'])) return false;
  }
 
  // Si no hay que filtrar nada, devolvemos "true" sino, ya habremos devuelto "false"
  return true;
}

Ahora sólo faltaría hacer un llamada:

$url = "http://www.ejemplo.ext/preba.html";
if(robots($url, "Agente")) {
  $contenido = file_get_contents($url);
}

Categorías Javier, PHP

Deja un comentario