Qué es el scraping y cómo hacerlo bien

Rigoberto Carvajal

Se conoce como scraping al arte de controlar de manera automatizada sitios web con el propósito de extraer datos publicados que son de nuestro interés. Este artículo es para personas familiarizadas con el scraping y en él encontrarán una serie de consejos y herramientas, trucos y diseños muy útiles cuando se trata de obtener muchos datos.

Esquema orquestador + browser

El mejor modelo para hacer scraping es en el que existe un programa “orquestador” que puede estar en cualquier lenguaje de programación y que controla a un explorador web. Es muy importante esto porque aunque uno pueda programar solicitudes http y parsear un html, hay sitios donde la interacción tiene que ser muy parecida a la que tiene un usuario con el navegador, sobre todo por la presencia de elementos AJAX y manipulación con Javascript, donde los elementos se consultan en la base de datos y se pintan sin que haya un cambio de página o refrescamiento. Objetos flash y applets de Java también pueden complicar la creación de scrapers, o la manera como están programados sitios en .Net, que guardan el estado de los objetos en la sesión web.

Orquestador: Programa en lenguaje de alto nivel con el que se puede aprovechar muchos recursos de la computadora y que envía comandos al explorador web para guiar la navegación deseada.

Explorador web: Es como una terminal “tonta”, no metemos lógica aquí, sino que es el componente capaz de manejar todos los elementos de una página web y sigue las instrucciones que el orquestador le da por medio de comandos.

Identificación de elementos

Cuando estamos procesando consultas en un motor, es muy importante que logremos identificar elementos que nos indiquen el estado final de la consulta, según sea exitosa, sin resultados o si hubo un error, si no hacemos esto podríamos estar tratando de aplicar acciones sobre los resultados sin que el sitio nos haya devuelto la respuesta completa todavía.

Continuar proceso interrumpido

Muchas razones pueden interrumpir un proceso de scraping, por ejemplo: una desconexión de internet, reinicio voluntario u obligatorio de la computadora, o que un error no contemplado bote la aplicación, etc. No hay que comenzar desde cero a scrapear todo el sitio. Se debería llevar un registro en una base de datos con los registros procesados, de manera que cuando se vuelva a ejecutar la aplicación pueda continuar donde quedó, sin depender de nosotros.

Observación de proceso

A veces podemos programar scrapers que no usen un explorador web visible sino que manejan las consultas y la lógica de extracción de datos sólo mediante código, lo que pasa con estos casos es que son más propensos a no capturar todos los datos, porque siempre aparecen casos y cosas que no habíamos considerado en la programación, por ejemplo es muy frecuente que algunos registros desplieguen un dato y hasta toda una pestaña de datos pero en otros no. Por lo que es una buena práctica observar la mayor cantidad de ejemplos posibles de los registros que vayamos a scrapear para estar más seguros que estamos considerando todos los escenarios posibles.

Captchas

A veces creemos que cuando un sitio tiene captcha es imposible de scrapear, pero no es así, actualmente existen librerías y muchos servicios web que resuelven los captchas y devuelven el texto que contienen las imágenes, y pueden ofrecer este servicio porque han desarrollado software para el reconocimiento de imágenes en combinación con inteligencia artificial o con personas, las cuales brindan la respuesta correcta cuando el sistema se equivoca y con esto el sistema sigue aprendiendo, manejando un rango entre 1 y 15 segundos la resolución del captcha.

Uno muy popular se llama DeathByCaptcha, tiene un excelente API y actualmente maneja un 92% de certeza y un tiempo promedio de 8 segundos en la respuesta.

División de trabajo y procesamiento en paralelo

Seguramente conocerás la frase “Divide y vencerás”, pues esta es una de las frases más aplicadas en la programación, así mismo al scraping. Si ya hemos experimentado con esto sabemos que scrapear un sitio puede tomar bastante tiempo de ejecución, la clave para mejorar esos tiempos está en dividir etapas del trabajo en diferentes programas y que trabajen de manera paralela, entendiéndose esto como varias instancias de los mismos programas ejecutándose al mismo tiempo en una o varias computadoras.

La manera más sencilla de scrapear es repitiendo la secuencia:

  • Consulto el registro X
  • Extraigo los datos
  • Los guardo en un archivo.

Esto funciona, pero no tanto cuando lo que queremos es scrapear más de 20.000 registros, a menos que estemos dispuestos a esperar todo ese tiempo. El siguiente esquema muestra un patrón de diseño que funciona muy bien para conjuntos de datos grandes y cuando los datos lo permitan:

En este modelo se divide el trabajo en 2 partes:

  • Consulta y guardado de página completa: el robot orquestador D se encarga de hacer las consultas en los formularios web y cuando obtiene los resultados los guarda como una página web completa en un folder de documentos que sirve un servidor web.
  • Extracción de datos y almacenamiento en base de datos: como las páginas web se están guardando en un servidor web, cualquier explorador web podrá visualizarlas como si fuera cualquier otro sitio, por lo que entonces aplicaremos nuevamente scraping a esas páginas que ahora correrán de manera local, con lo que se abrirán de inmediato y extraer sus datos va a ser más rápido.

La lógica de este diseño radica en los siguientes puntos:

  • La extracción de datos es más eficiente trabajando con páginas locales que en Internet porque el programa no tiene que esperar por los resultados de una consulta ni repetir intentos para leer cada uno de los campos a extraer.
  • Cuando descargo una página puedo identificar cual es el campo que se “pinta” en el browser como señal de éxito o de falta de resultados y sólo esperar en la programación por éste único elemento para dar la instrucción de guardar la página.
  • Si se cuenta con buen ancho de banda y varias computadoras aunque tengan poca capacidad de procesamiento este modelo es el más adecuado porque puedo tener a una(s) descargando y otra(s) extrayendo datos, y entre todas esas instancias el trabajo se hará en menor tiempo.
  • Si decido primero solo descargar puedo observar todos los posibles escenarios de resultados, por ejemplo: campos que solo se visualizan para ciertos valores y para otros no, podría identificar cuáles registros llevaron a una pantalla de error o de ausencia de datos sólo con el tamaño de las páginas HTML descargadas y descartarlos de una vez para no procesarlos.

La cantidad de descargadores debe ser congruente con nuestro ancho de banda; si usamos pocos podemos estar subutilizando los recursos, y si usamos demasiados habrá lucha por el recurso y tendremos a descargadores en “espera”. Hay que encontrar el balance, según el tamaño de los recursos que estemos descargando, el ancho de banda y la capacidad de procesamiento.

Para aplicar este modelo es indispensable utilizar un motor de base de datos multiusuario (como mssql, mysql o postgresql), pues éstos están hechos para controlar correctamente la concurrencia, dado que si pretendemos usar un archivo como un CSV o un archivo Excel habrá conflicto a la hora de que dos o más programas intenten escribir al mismo tiempo.

Segmentación

Para poder sacar provecho máximo del paralelismo es importante que repartamos la carga de trabajo entre varios “trabajadores”, sean estos instancias del programa en la misma computadora o programas corriendo en varias computadoras. Para esto podemos aplicar estrategias conocidas como la segmentación por rango y la segmentación por fórmulas.

Descargar un sitio entero

Una herramienta útil y fácil de utilizar es HTTrack, el cual se define como un copiador de sitios web, también sirve para este propósito el comando wget de UNIX/Linux. Está disponible en varios sistemas operativos y acompañado de algunas opciones y parámetros nos permite descargar todos los elementos estáticos del sitio y los modifica para que funcione localmente. Es importante aclarar que no trae aquellos objetos dinámicos del sitio a menos que sean accesibles desde links dentro del mismo sitio.

Este es un ejemplo usando HTTrack con la página de adquisiciones de la Asamblea Legislativa del Distrito Federal (México). Podemos descargar todas las páginas y documentos de ese sitio.

Crear un proyecto y definir la carpeta donde se va a descargar todo:

Definir las direcciones web para descargar:

Si hacemos clic en el botón de opciones se nos abrirá una pantalla donde podemos configurar nuestra descarga, por ejemplo definir los tipos de archivos que queremos incluir o excluir, de esta manera si sólo estamos interesados en descargar los documentos PDF de un sitio, podemos agregar una regla de la forma +*.pdf

Por ejemplo yo he agregado para este ejemplo que descargue los archivos de Excel también +*.xls + *.xlsx

La aplicación “navegará” por todas las páginas del sitio y se meterá en todos los links de cada página de manera recursiva, y mantendrá una lista de links descargándose, el tamaño por defecto de esa lista es de 4 conexiones, pero si cuenta con buen ancho de banda y capacidad de procesamiento puede aumentar ese valor en la pestaña de “Control de Flujo en la opción: Número de conexiones”.

Si desea entender cada una de las opciones puede dirigirse al manual del sitio, el cual cuenta con un paso a paso muy útil.

Habiendo configurado todo podemos dar clic a finalizar e inmediatamente veremos la aplicación descargar las páginas y archivos web.

Cuando todo este proceso haya finalizado tendrás una copia del momento del sitio web funcional corriendo desde tu computadora.

Recomendación final

Existen muchas herramientas hoy para hacer webscraping y todas las puedes tener en tu caja de herramientas, porque todas pueden funcionar para diferentes casos, pero es importante que consideres estos consejos y trucos para escoger las herramientas adecuadas en un proyecto de scraping.

Finalmente comparto mi caja principal de herramientas para web scraping :

Rigoberto Carvajal (@rcarvajal85)

Ingeniero en Computación graduado del Instituto Tecnológico de Costa Rica, con más de 7 años de experiencia en producción de software y administración de datos. Es experto en data del International Consortium of Investigative Journalists. Trabajó como Jefe Analista de Datos de la unidad de Investigación en La Nación de Costa Rica. Está a cargo de tareas de administración de bases de datos, procesos de extracción, transformación y carga; análisis y visualización de información, ha sido un caso exitoso de integración entre periodistas e ingenieros trabajando a diario en conjunto en el proceso de generación de noticias de interés público basadas en datos.

Un proyecto de               Gracias al apoyo de