Creando un scraper – Parte 1: introducción
Existen proyectos para los cuales necesitamos información que esté disponible en algún sitio web, ya sean comentarios, el precio de productos o cualquier tipo de dato. Si vamos a trabajar sobre un volumen grande de datos, sacar esa información de manera manual no siempre es viable, y tampoco tiene porque encontrarse de manera estructurada para poder trabajar con ella. Ésta es la motivación que me lleva a construir un scraper.
¿Qué es un scraper?
Un programa que se encarga de acceder a una página web y extraer la información que nos interesa de manera automatizada a un formato estructurado de manera que después nos sea de utilidad.
Existen multitud de implementaciones, herramientas y bibliotecas para montar un scraper, pero me parece un buen desafío conseguir implementar uno desde «casi» cero. Aunque tengo conocimientos acerca de la web, de cómo funciona y cuáles son los componentes y desafíos a la hora de montar una web, estoy seguro que este proyecto me enseñará un muchas cosas nuevas acerca de Internet, las técnicas de scraping y de antiscraping. Intentaré plasmarlas todas en este blog.
Cosas a tener en cuenta
Se me ocurren unos cuantos aspectos a tener en cuenta antes de abordar cualquier proyecto de scraping. Supongamos que queremos obtener TODOS los productos de, por ejemplo, Amazon.es, vamos a ver que aspectos hay que tener en consideración y si es un proyecto viable y bajo qué condiciones.
Conocer el tamaño del proyecto
El primero paso es investigar un poco acerca de nuestro objetivo. Si queremos tener información acerca de todos los productos de Amazon.es, lo primero es hacernos una idea de cuantos productos son. En hipertextual hablan de 157 millones a día de hoy.
Dos aspectos básicos a tener en cuenta a la hora de obtener información de 157 millones de productos son el tiempo que nos va a llevar obtenerlos y el dónde y cómo vamos a almacenar esa información. No sabemos a priori cuántas peticiones por segundo podremos hacer a Amazon.es ni cuántas de esas peticiones nos darán información de un producto, pero podemos hacer una estimación inicial. Supondremos 1 petición por segundo de manera inicial y que de cada 4 peticiones, 3 nos darán información nueva de producto. Ahora saquemos la calculadora:
Duración del scraping
El cálculo es fácil, 157.000.000 productos, a una tasa de 1 petición por segundo, con un factor de 3 productos cada 4 peticiones hacen:
157.000.000/1*4/3 = 209.333.333 segundos = 58.148 horas = 2.422 días = 6,6 años
6,6 años es una burrada de tiempo, una cantidad razonable de tiempo podrían ser 24 horas, para ello deberíamos hacer 58.148/24 = 2.422 peticiones por segundo, no todos los servidores de internet estan preparados para soportar esta carga, aunque supondremos que Amazon si.
Almacenamiento necesario
Posiblemente en nuestro proyecto no sea necesario almacenar todos los datos obtenidos. Si por ejemplo queremos hacer una media del precio de todos los productos tan sólo necesitaríamos el acumulado de precios y de productos, pero si vamos a querer almacenar los datos vamos a tener que hacer el cálculo de espacio necesario. Existen infinidad de manera de almacenar todos estos datos, pero vamos a calcularlo independientemente, suponiendo un almacenamiento de 1kB de datos por cada producto, entonces:
157.000.000 * 1kB = 157.000.000kB = 153.320MB = 149,7GB de datos.
150GB de datos actualmente no suponen ningún problema de almacenamiento, pero hemos hecho el cálculo con 1kb de datos, si nuestra predicción se queda corta y cada producto nos ocupa 10kB, el almacenamiento total será de 1,46 TB, que, aunque tampoco supone un problema de almacenamiento, es algo a tener en cuenta.
Tecnología a utilizar
Existen infinidad de opciones a la hora de desarrollar un scraper, cualquier lenguaje de programación que permita realizar conexiones con servidores y procesar la respuesta nos serviría, pero cuando estamos hablando de grandes números hay que escoger bien con qué trabajamos. Yo me he decidido por Node.js, puesto que está orientado a eventos y las peticiones de red no son bloqueantes. De esta manera puede realizar múltiples peticiones simultáneas al servidor de manera simultánea.
Aspectos no técnicos
No hay que tener en cuenta sólo los aspectos técnicos, tal vez la web sobre la que queremos hacer el scraping no quiere se objeto de un proceso de scraping, o directamente ofrece otros métodos para obtener esa información. Amazon, por ejemplo, ofrece una API para afiliados que te da información sobre los productos de la web, pero es bastante ilustrativo como ejemplo para hacer cálculos de un proyecto grande de scraping. Muchas páginas definen un archivo, llamado «robots.txt» que informa de qué zonas de la página web están accesibles para robots y cuáles no. El hacer caso de este fichero siempre queda a discreción del propio programa que haga el scraping.
La última cosa que siempre hay que tener en cuenta es que la carga de hacer una petición web es mucho menor que la carga que se genera al procesar la respuesta, y que si no tenemos cuidado con nuestros programas podemos causar problemas técnicos en los servidores donde se aloja nuestro «objetivo», por lo tanto tenemos que hacer las peticiones a un ritmo tal que no causemos una carga excesiva, aunque eso cause que nuestro proceso se alargue en el tiempo.
Resumiendo
Mi objetivo es crear un scraper desde cero, empezando por algo básico que, finalmente, sea capaz de escanear un sitio tan grande como Amazon.es en un periódo de tiempo comprensible. Empezaré por un programa sencillo que se ejecute desde mi ordenador y seguramente acabe convirtiéndose en un sistema distribuido y el programa inicial acabe convirtiéndose en un mero coordinador.