ESOFT 3 Nice Screen Scraper: A simple scraper Héctor López Sacanell hlopez1@alumnes.udl.cat 3 de diciembre de 2009 1. Introducción El objetivo de esta segunda entrega es la de crear una primera versión de la aplicación final que incluya el motor básico para obtener el código HTML de una web para posteriormente obtener la información deseada y guardarla en formato XML. La web que se ha utilizado en esta entrega es de la http://servicaixa. com, y más concretamente nos hemos centrado en la obtención de las películas en cartelera de una ciudad elegida por el usuario (ver Figura 1). Figura 1: servicaixa.com: web de donde sacaremos la información 1
2. Requisitos previos Antes de empezar a trabajar con el parseo de la web, necesitamos definir la estructura de datos que queremos obtener, esto es definir la DTD. Para tal efecto, hemos creado el fichero cartelera.dtd con la siguiente definición: <?xml version="1.0" encoding="utf-8"?> <!ELEMENT cartelera (pelicula)*> <!ATTLIST cartelera ciudad CDATA #REQUIRED> <!ELEMENT pelicula (titulo, enlace, calificacion, director)> <!ELEMENT titulo (#PCDATA)> <!ELEMENT enlace (#PCDATA)> <!ELEMENT calificacion (#PCDATA)> <!ELEMENT director (#PCDATA)> Y esta definición nos obligará a crear un fichero XML resultante que tenga un contenido parecido al que mostramos a continuación: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE cartelera SYSTEM "cartelera.dtd"> <cartelera ciudad="lleida"> <pelicula> <titulo></titulo> <enlace></enlace> <calificacion></calificacion> <director></director> </pelicula> </cartelera> 3. Obtención de la información Para poder obtener el contenido de la web necesitamos proceder de la siguiente manera: 1. Obtener el código HTML de la web elegida (servicaixa.com) 2. Convertir dicho código a XHTML para que el codigo fuente con el que trabajaremos esté bien formado. 3. Aplicar una hoja de estilos XSLT para realizar la transformación adecuada de los elementos deseados y crear el fichero final XML. 2
Para obtener y convertir el código HTML a código bien formado XHTML hemos utilizado la libreria jtidy. Y una vez que tenemos el árbol DOM definido y en memoria procedemos a tratarlo para generar el XML final. 3.1. Diseño de la web Para proceder con el diseño de la hoja de estilos XSLT primero hemos analizado la estructura de la información que queriamos capturar, la cual se puede ver en la siguiente Figura 5. Figura 2: Sección del código HTML a capturar En la cual se puede ver como toda la información está dentro de una tabla, cuyo identificador es id= tablalistado y cada película dentro de un tr con el atributo id definido. Dicha información es la que nos ha servido para identificar el contenido deseado. Si el usuario hace click en la película se realiza una petición AJAX al servidor y se descarga un fichero XML con la información de la película y se carga directamente en el mismo tr. Dicha información también está disponible en formato HTML 1. 1 Esta referencia (link) queremos utilizarla como parte de una ampliación de esta prácti- 3
3.2. Ajustes realizados Con motivo de la amplicación deseada y comentanda en el apartado anterior (3.1), hemos realizado unos ajustes en el árbol DOM generado originalmente. Dichos cambios han sido los de añadir un nuevo elemento dentro del nodo <head>. El nuevo elemento ha sido la etiqueta <base> y cuyo contenido ha sido el de la dirección URL base de la web (http://www.servicaixa.com). Este ajuste ha sido necesario para poder disponer de una URL absoluta que nos identifique la localización física de la descripción completa de la película en cuestión, ya que sino, únicamente dispondríamos de una dirección relativa, y nunca sabríamos el dominio original. Este ajuste se ha realizado utilizando las funcionalidades de XPath. 3.3. Raspado final Con el árbol DOM generado y ajustado a nuestras necesidades, hemos diseñado la hoja de estilos XSLT (servicaixa.xsl) adecuada, para realizar las transformaciones pertinentes en la web original, para generarnos un fichero XML final, con el nombre de la ciudad consultada. En el siguiente bloque de código se muestra parte del contenido XML final correspondiente a la cartelera de Lleida: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE cartelera SYSTEM "cartelera.dtd"> <cartelera ciudad="lleida"> <pelicula> <titulo>amelia</titulo> <enlace>http://www.servicaixa.com/nav/es/cine/amelia/lleida/index.html</enlace> <calificacion/> <director>mira Nair</director> </pelicula> <pelicula> <titulo>celda 211</titulo> <enlace>http://www.servicaixa.com/nav/es/cine/celda_211/lleida/index.html</enlace> <calificacion/> <director>daniel Monzón</director> </pelicula>... </cartelera> ca para obtener dinámicamente dicha información y mostrarla en el fichero XML final. 4
4. Posible amplición Hemos pensado en realizar una posible ampliación al actual contenido añadiendo el contenido completo de la película, cosas como: valoración, cartel, sinopsis, etc. Esta información tambien la proporciona la web de servicaixa.com y además la proporciona en formato HTML y en XML. Cada una de las películas analizadas incluye una referencia (link) a su descripción completa (ver Figura 3), y además incluye una petición AJAX con la definición del XML a utilizar (ver Figura 4), con lo que disponemos de todas las herramientas y elementos para realizarlo. Figura 3: Detalle de la película 5
Figura 4: Fichero XML con el detalle de la película La principal idea es la de crear un nuevo XSLT y ejectura la transformación en cada uno de los elementos película, durante o después del proceso de transformación de la cartelera (está por decidir). Una vez obtengamos el detalle de cada una de las películas, éste se incluirá en el fichero XML. Para ello también tendremos que ampliar la DTD definida. 5. Ejecución Para poder generar nuevos ficheros XML con la cartelera de la ciudad deseada, únicamente se tiene que ejecutar el script run tal y como se muestra en el siguiente ejemplo: $./run lleida linea 554 columna 18 -Error:<numestrellas> falta > al final de la etiqueta linea 554 columna 18 -Error:<numestrellas> no se reconoce! linea 606 columna 18 -Error:<numestrellas> falta > al final de la etiqueta linea 606 columna 18 -Error:<numestrellas> no se reconoce! linea 623 columna 18 -Error:<voto> falta > al final de la etiqueta linea 623 columna 18 -Error:<voto> no se reconoce! XML file generated in: Lleida.xml Como se ve, se han dejado activos los errores producidos por la transformación de HTML a XHTML, para disponer de más información y validar el proceso final. El script recibe por parámetro el nombre de la ciudad tal y como aparece en la URL de servicaixa.com, para lleida es: 6
Figura 5: Ciudad elegida codificada en la URL El script también se puede ejecutar sin parámetros, con lo que obtendrá por defecto al cartelera de Lleida. 6. Código Fuente Todo el código fuente se encuentra disponible en la web del proyecto SimpleNiceScreenScraper en Google code. http://code.google.com/p/nicescreenscraper 7