Web Scraping con Node.js

    Introducci贸n

    Por definici贸n, web scraping significa obtener informaci贸n 煤til de las p谩ginas web. El proceso deber铆a eliminar la molestia de tener que navegar por las p谩ginas manualmente, ser automatizado y permitir recopilar y clasificar la informaci贸n que le interesa mediante programaci贸n.

    Node.js es una gran herramienta para usar en web scraping. Permite implementar rutinas de web scraping en un par de l铆neas de c贸digo utilizando el m贸dulo de c贸digo abierto proporcionado por npm – el Administrador de paquetes de node.

    Los pasos principales del web scraping

    Como ya hemos definido, el web scraping no es m谩s que automatizar la navegaci贸n manual y la recopilaci贸n de informaci贸n de sitios web espec铆ficos en su navegador web preferido.

    Este proceso consta de 3 pasos principales:

    • Obtener el c贸digo fuente HTML del sitio web
    • Dar sentido al contenido HTML, encontrar la informaci贸n que nos interesa y extraerla
    • Mover la informaci贸n descubierta al almacenamiento de su elecci贸n (archivo de texto, base de datos, etc.)

    Los primeros y 煤ltimos pasos suelen ser pr谩cticamente los mismos, seg煤n los requisitos de su aplicaci贸n. Sin embargo, entender el contenido HTML requiere que escriba un c贸digo espec铆fico para cada sitio web que le gustar铆a raspar.

    Precauci贸n

    Dependiendo de su uso de estas t茅cnicas y tecnolog铆as, su aplicaci贸n podr铆a estar realizando acciones ilegales.

    Hay algunos casos en los que deber铆a tener cuidado con:

    • DoS – UN Ataque de denegaci贸n de servicio pr谩cticamente depende de enviar tantas solicitudes al servidor que simplemente no puede manejar m谩s. Entonces se rechazar铆an todas las nuevas solicitudes entrantes. Si raspa un sitio web con demasiada frecuencia, puede considerarse un ataque DoS.
    • T茅rminos de servicio – Muchos sitios web, y casi todos los sitios web m谩s grandes, establecen claramente que el web scraping en sus plataformas est谩 prohibido. Si mucha gente eliminara estos sitios web, terminar铆a siendo un DDoS ataque, que en s铆 mismo es ilegal.
    • Software abusivo – Muchas herramientas y marcos en l铆nea ofrecen una gran variedad de herramientas y funcionalidades. Algunos permiten a los usuarios completar formularios, enviar datos, cargar y descargar archivos, etc. CAPTCHA se utiliza para combatir esto, sin embargo, incluso esto se puede superar con un bot.

    Algoritmo de raspado web manual

    Como ejemplo, buscaremos el P谩ginas Amarillas para empresas que prestan servicios de impresi贸n en Nueva York.

    En primer lugar, definamos nuestra tarea y el resultado deseado:

    Produzca una lista de las empresas que prestan servicios de impresi贸n en Nueva York en forma de archivo “.CSV” que debe tener el nombre de la empresa, el correo electr贸nico, el tel茅fono y las columnas de enlace que describan a cada empresa.

    As铆 es como lo har铆amos manualmente:

    • Navegue con nuestro navegador hasta el enlace correspondiente y ponga “impresi贸n” y “Nueva York” en los campos de b煤squeda y ejecute la b煤squeda.
    • Seleccionar y almacenar el nombre de la primera empresa de la lista
    • Almacene el enlace a la p谩gina de la empresa y s铆galo
    • Encuentra una direcci贸n de correo electr贸nico y gu谩rdala
    • Escriba los valores almacenados en un archivo “.CSV” mediante un editor de texto u otra herramienta para editar tablas como Excel o Google Sheets

    Repetir estos pasos varias veces nos dar谩 una tabla llena de detalles de la empresa.

    Automatizar el proceso con Web Scraping

    Para automatizar el proceso, debemos seguir los mismos pasos mediante programaci贸n.

    Configuraci贸n del entorno de desarrollo

    Usaremos Node.js y npm para desarrollar este proyecto de muestra. As铆 que aseg煤rese de que esas herramientas est茅n instaladas en su m谩quina y comencemos ejecutando el siguiente comando en un directorio vac铆o de su elecci贸n seguido de la creaci贸n de un index.js p谩gina que contendr谩 nuestro c贸digo:

    $ npm init
    

    El siguiente paso es instalar los m贸dulos necesarios del npm.

    A partir del algoritmo manual descrito anteriormente, vemos que necesitaremos algo para obtener el c贸digo fuente HTML, analizar el contenido y darle sentido y luego escribir la matriz de objetos JavaScript en el archivo “.CSV”:

    $ npm install --save request request-promise cheerio objects-to-csv
    

    Al ejecutar la l铆nea anterior en el terminal se instalar谩n los m贸dulos requeridos en el node_modules directorio y gu谩rdelos como dependencias en el package.json archivo.

    Recuperaci贸n de informaci贸n

    Una vez realizada toda la preparaci贸n, puede abrir el index.js archivo en su editor de texto favorito y requiere los m贸dulos que acabamos de instalar:

    const rp = require('request-promise');
    const otcsv = require('objects-to-csv');
    const cheerio = require('cheerio');
    

    Completar este paso en el algoritmo manual nos dar谩 el enlace, que dividiremos en dos partes y agregaremos al index.js justo despu茅s de los m贸dulos:

    const baseURL = 'https://www.yellowpages.com';
    const searchURL = '/search?search_terms=printing&geo_location_terms=New+York%2C+NY';
    

    Luego, deber铆amos escribir una funci贸n, que devolver谩 la matriz de objetos JavaScript que representan las empresas de la descripci贸n de la tarea.

    Para poder traducir el algoritmo manual en c贸digo, primero tendremos que hacer un trabajo manual usando el inspector herramienta de nuestro navegador web.

    Necesitaremos encontrar los elementos HTML espec铆ficos que contienen la informaci贸n que nos interesa. En nuestro caso, el nombre de la empresa se puede encontrar en un elemento como:

    <a class="business-name" href="/new-york-ny/mip/global-copy-2988131?lid=1000106255864" itemprop="name">Global Copy</a>
    

    Que es un <a> etiqueta con la clase business-name, que tiene el nombre de la empresa y un href propiedad que contiene un enlace a la p谩gina de la empresa individual. Ambos nos ser谩n 煤tiles en el futuro.

    Siguiendo el enlace a la p谩gina de la empresa, necesitaremos encontrar los dos datos restantes: el tel茅fono y el correo electr贸nico. Est谩n ubicados debajo del <p> etiquetas con la clase phone y el <a> etiqueta con la clase email-business.

    Tenga en cuenta que para obtener el tel茅fono, necesitaremos el valor almacenado dentro de la etiqueta y para recibir un correo electr贸nico, necesitaremos un href propiedad de la <a> etiqueta.

    Veamos c贸mo se ver谩 el algoritmo manual cuando intentemos implementarlo program谩ticamente:

    • Obtenga el c贸digo fuente HTML de la p谩gina que estamos buscando raspar usando el request-promise m贸dulo y aliment谩ndolo con un enlace que obtuvimos en el primer paso de nuestro algoritmo manual
    • Asigne la matriz de nombres de empresas en el HTML original en una matriz de objetos con el nombre de las propiedades, el enlace, el tel茅fono y el correo electr贸nico.
    • Convierta la matriz resultante en un archivo CSV

    As铆 es como se ver谩 este algoritmo cuando se implemente:

    const getCompanies = async () => {
      const html = await rp(baseURL + searchURL);
      const businessMap = cheerio('a.business-name', html).map(async (i, e) => {
        const link = baseURL + e.attribs.href;
        const innerHtml = await rp(link);
        const emailAddress = cheerio('a.email-business', innerHtml).prop('href');
        const name = e.children[0].data;
        const phone = cheerio('p.phone', innerHtml).text();
    
        return {
          emailAddress,
          link,
          name,
          phone,
        }
      }).get();
      return Promise.all(businessMap);
    };
    

    Sigue las reglas que hemos configurado anteriormente y devuelve un Promise que se resuelve en una matriz de objetos JavaScript:

    {
      "emailAddress": "mailto:[email聽protected]",
      "link": "https://www.yellowpages.com/new-york-ny/mip/global-copy-2988131?lid=1000106255864",
      "name": "Global Copy",
      "phone": "(212) 222-2679"
    }
    

    Promesa

    En caso de que no est茅 familiarizado con los conceptos b谩sicos de la programaci贸n asincr贸nica en JavaScript moderno, aqu铆 hay una breve introducci贸n a Promises.

    UN Promise es un tipo especial que act煤a como marcador de posici贸n para el valor. Podr铆a estar en un par de estados:

    • pendiente
    • cumplido
    • rechazado

    Sin ser demasiado detallado al respecto, debe saber que las funciones que devuelven promesas no devuelven los valores reales. Para acceder al resultado de la Promesa o al valor de resoluci贸n, debe escribir otra funci贸n, que debe pasarse al then bloquear y esperar el valor con el que se resolver谩 el prometido. Si ocurre alg煤n error dentro de la Promesa mientras est谩 pending, luego pasar谩 al rejected estado con la posibilidad de manejar el error en el catch bloquear.

    Almacenamiento de datos y toques finales

    Aunque el resultado parece bastante bueno, al observar m谩s de cerca el conjunto de empresas, nos muestra que el correo electr贸nico tiene un mailto: prefijo y, a veces, faltan los correos electr贸nicos y los nombres de las empresas:

    {
      "emailAddress": undefined,
      "link": "https://www.yellowpages.com/new-york-ny/mip/apm-451909424?lid=451909424",
      "name": undefined,
      "phone": "(212) 856-9800"
    }
    

    Volviendo a la herramienta del inspector, vemos que el nombre de la empresa tambi茅n se puede encontrar en la p谩gina interna de la empresa dentro de un <h1> etiqueta.

    Los correos electr贸nicos a veces faltan para ciertas empresas y no podemos hacer nada al respecto.

    los mailto: El prefijo se puede eliminar usando un replace funci贸n.

    Estos son los ajustes que debe realizar en su c贸digo:

    ...
        const name = e.children[0].data || cheerio('h1', innerHtml).text();
    ...
        emailAddress: emailAddress ? emailAddress.replace('mailto:', '') : '',
    ...
    

    Ahora que hemos extra铆do todos los datos necesarios de la p谩gina web y tenemos una matriz limpia de objetos JavaScript, podemos preparar el archivo “.CSV” requerido por nuestra definici贸n de tarea:

    getCompanies()
      .then(result => {
        const transformed = new otcsv(result);
        return transformed.toDisk('./output.csv');
      })
      .then(() => console.log('SUCCESSFULLY COMPLETED THE WEB SCRAPING SAMPLE'));
    

    los getCompanies La funci贸n devuelve una promesa que se resuelve en una matriz de objetos preparados para ser escritos en el archivo CSV, que se realiza en la primera then bloquear. El segundo se resuelve cuando el archivo CSV se escribe correctamente en el sistema de archivos, completando as铆 la tarea.

    Al agregar este fragmento de c贸digo a nuestro index.js archivo y ejecutarlo con:

    $ node index.js
    

    Deber铆amos conseguir un output.csv archivo directamente en nuestro directorio de trabajo. La tabla representada por este .CSV el archivo contiene 4 columnas – emailAddress, link, name, phoney cada fila describe una sola empresa.

    Conclusi贸n

    En esencia, el web scraping consiste en navegar por p谩ginas web, recoger informaci贸n 煤til de acuerdo con la tarea y almacenarla en alg煤n lugar, todo lo cual se hace mediante programaci贸n. Para poder hacer esto con c贸digo, este proceso debe realizarse primero manualmente usando un inspector herramienta del navegador o analizando el contenido HTML sin procesar de la p谩gina web de destino.

    Node.js proporciona herramientas confiables y simples para hacer del web scraping una tarea sencilla que podr铆a ahorrarle mucho tiempo en comparaci贸n con procesar los enlaces manualmente.

    Aunque puede parecer tentador automatizar todas sus tareas diarias como esta, tenga cuidado cuando se trata de usar estas herramientas, porque es f谩cil violar los t茅rminos de servicio de un sitio web si no lo ha le铆do por completo, o incluso simplemente generando una gran cantidad de tr谩fico con su raspador.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *