Web Scraping con Python

Pues debido a una colaboración solicitada por un compañero de la oficina, experto en Big Data el caballero, tenía como tarea hacer algo de web scraping… lo intenté primero con PHP y la librería PHPCrawl, sin embargo a pesar de ser mas asiduo de este lenguaje (por los años de uso) no fue posible lograr mi propósito, de cualquier forma la recomiendo pues se ve bastante sencilla y directa.

Otra opción fue utilizar python, al cual le he agarrado mas “cariño” últimamente, y buscando me encontré con el proyecto scrapy que por lo visto es bastante usado, logré pasar exitosa y sencillamente la autenticación del sitio que deseábamos trabajar y hacer una pequeña función recursiva para ir obteniendo links y guardando páginas. Les dejo un código de ejemplo explicado y sencillo para descargar en formato html las páginas de “determinado” sitio, en este caso apunta a http://gmo.betanzos.org, incluí comentarios para indicar lo que para mí son las partes de código mas significativas.

import scrapy

class wc(scrapy.Spider):
    # Nombre del "spider"
    name="wc"
    # Dominios permitidos, puedes incluir mas de uno separando
    # con comas
    allowed_domains=["gmo.betanzos.org"]
    #Url donde inicia    
    start_urls=["http://gmo.betanzos.org"] 
    
    def parse(self, response):
        # Asignando el nombre a un archivo en base
        # a la url
        filename=response.url.split("/")[-2] + '.html'
        with open(filename, 'wb') as f:
            # Guardando el body de la pagina en un archivo 
            # con extension html
            f.write(response.body) 

        # Via el metodo css recuperamos los 
        # enlaces de la pagina
        for href in response.css("ul > li > a::attr('href')"): 
            url=response.urljoin(href.extract())
            # Imprimimos las urls a manera de debugging
            self.log(url)
            # Llamamos de nuevo a parse con la nueva url que
            # que deseamos procesar
            yield scrapy.Request(url,callback=self.parse)

Esto lo invocan vía shell de la siguiente manera:

$ scrapy crawl wc

Y en este caso como resultado obtuvo la siguiente lista de archivos html:

[11:31:09] betanzos@localhost ~ > ls *.html
-rw-r--r-- 1 20066 Apr 29 20:40 android.html
-rw-r--r-- 1 17075 Apr 29 20:40 apple.html
-rw-r--r-- 1 16894 Apr 29 20:40 bases-de-datos.html
-rw-r--r-- 1 8245 Apr 29 20:41 connect.html
-rw-r--r-- 1 16695 Apr 29 20:40 education.html
... etc

¡Saludos!