Web Scraping con Node.js

W

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.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad