domingo, 18 de agosto de 2019

Crear un scraper de productos de Supermercado con Python

Scrapper de Supermercado
Hola!

Hoy traigo algo un poco distinto a lo que venía subiendo que tuve que hacer como tarea previa para un Trabajo Practico de la Universidad (que sigue en desarrollo).

El trabajo consiste en realizar una aplicación web y la nuestra necesita tener los datos de los precios de los productos de los supermercados. Idealmente en el futuro, los supermercados podrán ofrecer una vía directa para que la aplicación consulte los precios o la misma aplicación les dejará subir o actualizar sus precios. Por ahora como la aplicación es nada más una prueba de concepto, basta con tomar los datos de un supermercado y a partir de ellos crear nuevos precios para simular que tenemos los datos de varios supermercados.

La primera idea que se nos ocurrió para obtener los precios de todos los productos fue utilizar algún Framework como Selenium que permite la automatización de un navegador web y agarrar y copiar los valores de los atributos html de la página.

Por ejemplo si un supermercado lista sus productos con una lista de html tendría algo así:

<li id="producto1" ..> 
     <div>
        <p class="nombreprod">Nombre producto</p>
        <p class="precioprod">Precio</p>
        <p class="catprod">Categoría</p>
       ...
     </div>
</li>
<li id="producto2"..>
...
Entonces nosotros podríamos agarrar uno por uno cada elemento de la lista y guardarlo en algún tipo de diccionario de python para luego transformarlo en un archivo .json.
Esto sin embargo lleva mucho tiempo ya que (siguiendo el ejemplo) si no se tiene la clase "nombreprod", no habría una "forma directa" de acceder al nombre del producto entonces tendríamos que buscar otra forma de acceder a ese atributo que podría ser utilizando el path absoluto "body/div/div/div/div/table/..." que con páginas grandes puede llevar mucho tiempo calcular cada path.

Por eso tratamos de evitar esta opción y nos preguntamos si la página para recibir los productos podría utilizar un archivo .json en donde estén todos los datos guardados y arme el html en base a eso.

Por suerte este es el caso de Jumbo y de Dia. Decidimos enfocarnos en Jumbo ya que fue el primero que encontramos.

Si accedemos por ejemplo a este link podemos ver que se está haciendo algún tipo de búsqueda entre los primeros 50 elementos y se retorna el json de cada elemento. En cada item se encuentra el precio, la descripción, url de la imágen, categorías y mucha información más.

Nosotros lo único que necesitábamos por el momento es el precio, nombre, descripción e imagen, tal vez algún atributo más pero el archivo original contiene demasiada información de más que no nos servía.

Entonces el siguiente paso era filtrar solo la información que queríamos y automatizar para que lo haga con todos los productos.

Para eso decidí crear un script en python que se encarga de hacer lo siguiente:
  1. Descargar e interpretar el archivo json de a 50 items (cambiando los valores from y to del url).
  2. Agarrar la información que necesitábamos y colocarla en un diccionario nuevo.
  3. Repetir los pasos 1 y 2 hasta que no hayan más productos disponibles (que el url nos indique un error).
  4. Volcar toda esta información en nuestro propio archivo .json.
 Así de simple en menos de 50 líneas (con comentarios) pude crear el scraper:



Después descubrimos que el supermercado Día también utiliza archivos json para listar sus productos así que se podría adaptar este programa para scrapear también los precios de Día pero ahí nos encontraríamos en un problema: ¿Cómo podemos relacionar 2 productos iguales de distintos supermercados? No tenemos garantía de que un supermercado tenga por convención "NombreProducto-Marca" y otro "Marca-NombreProducto". 

Después descubrimos que por producto existe un código único llamado "ean" para igualarlos así que existe la posibilidad de relacionar dos productos iguales de distintos supermercados pero eso lo dejamos para el futuro.

Esto puede abrir la puerta a cuestiones más interesantes como ir rastreando la variación de precios a lo largo del mes o del año (ejecutando el mismo script y recopilando la información) que con información de varios supermercados podría servir como indicador de inflación y otras cosas.

Pero bueno, por ahora nos conformamos con tener solo esta información para nuestro trabajo, tal vez en el futuro explote un poco más este tema.

Hasta la próxima.

-L