Crawler

Anuncio
Recuperación y Acceso a la Información
Implementación de un Crawler Básico
Objetivo
Creación de un crawler sencillo para obtener documentos de la Web (páginas HTML) y construir un corpus documental
sobre el que funcionará el motor de búsqueda.
Requisitos
El crawler se desarrollará en C#, y se deberá implementar una librería con toda la funcionalidad. Esta librería será
utilizada posteriormente por el motor de búsqueda.
Las URLs que el crawler visita deberán almacenarse con un mecanismo de persistencia. Para ello, se utilizará una base de
datos SQLite en la que almacenar toda la información relevante de crawling. Además, el contenido de las páginas deberá
almacenarse en un directorio del disco duro.
Recursos
Se entrega una solución de Visual Studio 2005 con el código base, en el cual habrá que rellenar varios huecos. La solución
contiene un proyecto llamado RAI.Crawler, que es la librería con toda la funcionalidad del crawler, y otro proyecto llamado
Run, que se usará simplemente para instanciar un crawler e iniciarlo. Además, se incluye también la librería
System.Data.SQLite, para trabajar con la base de datos desde el crawler. También, se entrega una pequeña herramienta con
GUI para manipular manualmente el contenido de la base de datos.
Estructura
La estructura del crawler se muestra a continuación:
1
Recuperación y Acceso a la Información
La clase Uri2 nos servirá como contenedor de las URLs que se visiten, conteniendo cierta información de control necesaria
para el proceso. Cada instancia deberá corresponderse con una fila de la base de datos. Tanto las instancias como las filas
de la base de datos contienen:






Id: identificador de la URL (clave primaria en la tabla de la base de datos).
Uri: URL correspondiente.
Parent: identificador de la URL de la página que contenía el enlace a esta página. Las URLs semilla no tienen
Parent.
Level: nivel de la página en el correspondiente árbol de enlaces (siempre uno más que el padre). El nivel de las
URL semilla será 1.
Cache: path del archivo local que contiene el contenido de la página.
Success: estado de la URL. Null si no se ha procesado, y true o false dependiendo de si se procesó bien o hubo
algún error.
La clase Uri2 provee 3 formas de construir instancias:



CreateSeed, para crear URLs que se usarán como semilla en el proceso de crawling.
CreateFromDatabase, para instanciar las URLs que se lean de la base de datos.
CreateCustom, para crear URLs nuevas sacadas de los enlaces de alguna página.
IUriProvider especifica las operaciones del mecanismo de persistencia a usar. Habrá que inicializarlo primeramente, y
después se le podrán pedir URLs para procesar con GetUri(), se podrán añadir URLs nuevas con AddUri(Uri2) y se
actualizarán después de ser procesadas con Update(Uri2). En nuestro caso, SQLiteUriProvider será la clase encargada de
ofrecer persistencia con la base de datos. Contiene una conexión a la misma y tres comandos SQL, uno para cada
operación.
La clase Settings se usa para encapsular la configuración del crawler, que se guarda en un archivo XML. Contiene 3
parámetros:



DBFile: path al archivo de la base de datos SQLite.
DownloadAttempts: número máximo de intentos para bajar una página.
MaxLevels: número máximo de niveles por los que navegar en el árbol de enlaces.
La clase Crawler es la encargada de juntar todo lo anterior. Contiene una configuración en _settings, y un proveedor de
URLs en _uriProvider. Deberá instanciarse con el path del archivo de configuración. Se podrá usar para añadir semillas con
la operación AddSeed(string), y se iniciará el proceso de crawling con el método Start(). Además, internamente, ofrece la
operación GetCacheFilename(), que se encargará de devolver un path único para guardar el contenido de la página
correspondiente.
La estructura local de archivos estará formada por 100 directorios, del 00 al 99. Dentro de cada uno, estarán los archivos
correspondientes a las caches de las páginas. Cuando se pida un nombre de archivo con el método GetCacheFilename(), se
escogerá uno de los directorios aleatoriamente y después un archivo con nombre único dentro del mismo.
Partes a Completar
Se deberán completar los tres constructores de Uri2. También la operación Update(Uri2) del SQLiteUriProvider. Dentro de
la clase Crawler, debe inicializarse el _uriProvider en el constructor, e implementar las operaciones AddSeed(string), Start()
y GetCacheFilename().
2
Recuperación y Acceso a la Información
Discusión e Implementación de Mejoras
Uso del Crawler en la Asignatura
El crawler que se desarrolla se usará para obtener documentos y crear un repositorio local que servirá de base para el
motor de búsqueda. Como se trata de una prueba de concepto, y no de un sistema a gran escala, las semillas que se darán
al crawler serán páginas que nos proporcionen documentos relevantes, en principio, para nuestros propósitos.
El motor de búsqueda de las siguientes prácticas se evaluará con una serie de consultas. La forma que vamos a tener de
obtener documentos relevantes es utilizar Google como ayuda. De esta forma, al crawler se le dará una semilla por cada
una de las consultas que se realizarán sobre el motor de búsqueda, y estas semillas serán simplemente consultas sobre
Google que nos den documentos relativos a esa consulta.
Por ejemplo: si una de nuestras consultas es relativa a la influencia del vino tinto sobre la probabilidad de sufrir un ataque
al corazón, la semilla correspondiente podría ser una consulta a Google con los términos vino tinto ataque corazón. Es
decir, la semilla para el crawler sería http://www.google.es/search?q=vino+tinto+ataque+corazón. A partir de ella, el
crawler irá navegado por las páginas de resultados que, potencialmente, serán relevantes a la hora de realizar la consulta
sobre nuestro motor de búsqueda. Este proceso se repetiría por cada consulta que vayamos a evaluar en la asignatura.
Posibles Mejoras
De todas las mejoras que se muestran a continuación, cada grupo deberá implementar al menos una en su crawler, a
elegir entre:
1.
2.
3.
4.
5.
6.
7.
8.
Captura de enlaces. Muchas páginas no siguen el estándar XHTML, por lo que la sintaxis seguida para los enlaces
no es necesariamente <a href="http://...">...</a>. Algunas páginas usan comillas simples (<a
href='http://...'>...</a>). Otras no usan delimitadores (<a href=http://...>...</a>). Además, es posible que las URLs
de
interés
estén
incrustadas
dentro
de
otras
(por
ejemplo
con
Google):
<a href="http://origen.es/redirige.php?destino=http://destino.es/pagina.html">...</a>. Incluso, puede que la
etiqueta esté en mayúscula: <A Href="...">...</a>.
Comprobación de tipo de documento. No todos los enlaces que aparezcan serán páginas HTML, muchos serán
imágenes, documentos PDF, etc. Se podría comprobar cuál es el tipo MIME (campo content-type de la cabecera
HTTP), y guardar el documento sólo si es una página HTML. Podría incluso implementarse un pequeño filtro para
asegurarse, porque muchos servidores Web no devuelven el tipo MIME correcto.
Limitación del tamaño del documento. Puede darse el caso en que una página sea demasiado grande (incluso
del orden de gigabytes). Se podría limitar el tamaño de los archivos a bajar (campo content-length de la cabecera
HTTP).
Almacenamiento de archivos en memoria. Para no dar demasiado trabajo al disco duro, en lugar de descargar
todos los archivos a disco, y después borrarlos si no nos interesa el documento (ver mejora 2), podría
almacenarse en un buffer de memoria y guardarlo en disco sólo si es de interés, incluso considerando límites de
tamaño en el buffer (ver mejora 3).
Tratamiento específico de semillas. Dado que las semillas serán consultas a Google, se podrían tratar de forma
específica para capturar enlaces a documentos, ignorar los enlaces a búsquedas en otros servicios (News, Books,
Youtube, etc), navegar por las páginas de resultados, etc.
Peticiones avanzadas. Para evitar que los sites se den cuenta de que les está visitando un crawler, se pueden
hacer peticiones más avanzadas. Por ejemplo, incluir el campo user-agent con información del sistema del cliente
(sistema operativo, navegador, etc.), uso del campo referer, utilización de las cookies del servidor, etc. También se
pueden controlar las redirecciones que un servidor intente hacer ante una petición, o hacer peticiones cada cierto
tiempo, para evitar sobrecargar los servidores.
Uso de varios protocolos. Puede haber resultados con protocolos diferentes a HTTP, por ejemplo FTP o HTTPS.
Se podrían incluir estos documentos también, incluso permitiendo que el certificado de un site HTTPS no sea
válido.
Control de duplicados. Puede que un mismo documento corresponda a URLs diferentes. Podría controlarse esto
mediante algún campo UNIQUE en la base de datos que no permita insertar duplicados (esto ya se hace con el
campo Uri). Por ejemplo, se podría calcular el hash MD5 de los documentos.
3
Recuperación y Acceso a la Información
9.
Normalización de URLs. Podrían tratarse como idénticas URLs que cambien sólo en el orden de sus parámetros.
Por
ejemplo
http://dev.es/show.php?id=34&order=author
es
equivalente
a
http://dev.es/show.php?order=author&id=34. También es posible que aparezcan caracteres de escape en los
enlaces: http://es.wikipedia.org/wiki/España se escaparía como http://es.wikipedia.org/wiki/Espa%C3%B1a, pero
son la misma URL.
10. Tratamiento inteligente de niveles. Si una URL ya está en la base de datos con el nivel máximo permitido, ya no
seguirá utilizándose para obtener nuevos enlaces. Sin embargo, si aparece repetida, por venir de otra página
padre (ver mejoras 8 y 9) podría ser con nivel menor. En ese caso, se podría actualizar el nivel en la base de datos
para seguir navegando por ella.
11. Distribución del proceso. Lo normal es que un crawler funcione en varias máquinas y con varios threads. Ello
implica implementar ciertos mecanismos de concurrencia para evitar que distintos threads procesen las mismas
páginas, intenten guardarlas en el mismo archivo local, etc.
Sugerencias
Para controlar más las cabeceras y protocolos, se pueden utilizar las clases System.Net.WebRequest y
System.Net.WebResponse, que tienen una propiedad Headers. Para utilizar buffers en memoria se puede utilizar la clase
System.IO.MemoryStream. Para calcular hashes consultar la clase System.Security.Cryptography.MD5. Para trabajar con
certificados
de
HTTPS,
consultar
la
propiedad
ServerCertificateValidationCallback
de
la
clase
System.Net.ServicePointManager. Para utilizar threads consultar System.Threading.Thread y la construcción lock the C#
para sincronización.
Para posibles valores del user-agent, mirar http://www.user-agents.org. Para posibles valores del tipo MIME mirar
http://www.webmaster-toolkit.com/mime-types.shtml.
Entrega
Deberá entregarse la solución de Visual Studio con el código del crawler de cada grupo, además de una pequeña memoria
explicando la mejora implementada.
La práctica deberá entregarse por Aula Global. El día de la entrega se procederá a la corrección presencial en clase, por lo
que todos los grupos deberán asegurarse de que su crawler funciona en los ordenadores del aula.
Evaluación
La primera parte (crawler básico) se evaluará hasta un máximo de 7 puntos, considerando la corrección de la solución
implementada. La segunda parte (mejoras) se evaluará hasta un máximo de 3 puntos, teniendo en cuenta el número de
mejoras y su complejidad.
4
Descargar