81

Extrayendo datos de la Secretaría de Hacienda con scraping en Node.js

2497Puntos

hace 3 años

Node.js es un entorno en tiempo de ejecución multiplataforma y es una de las tecnologías líderes cuando hablamos de áreas como backend y desarrollo de aplicaciones de lado de servidor.

En el Curso de fundamentos de Node.js, se explican detalles y fundamentos básicos que nos permitirán iniciar de cero en esta increíble y potente tecnología.

Ahora, vayamos al grano. En este blog les explicaré paso a paso como extraer datos del Diario Oficial de la Federación.

El Diario Oficial de la Federación (DOF) es el periódico oficial del gobierno mexicano. Su función es la publicación de leyes, acuerdos, circulares, órdenes y todos los actos expedidos por los poderes de la Federación, con el fin de que sean observados y aplicados debidamente en sus respectivos ámbitos de competencia.

En este Diario, la Secretaría de Hacienda y en específico el Servicio de Administración Tributaria (SAT), publica de manera periódica la lista de **PRESUNTAS “**empresas fantasma” o “empresas de papel” a las que se les da un plazo de 15 días hábiles para presentar ante las oficinas de las autoridades un escrito libre en original y dos copias firmado por el contribuyente o su representante legal en el que manifiesten y anexen documentación e información que desvirtúen los hechos que llevaron a la autoridad a notificarlos.

Algunos de los motivos por los cuales se notifica, son emitir comprobantes fiscales sin contar con:

  • Los activos.
  • El personal.
  • La infraestructura o capacidad material para prestar los servicios o entregar los bienes que amparen tales comprobantes.

Para fines prácticos, utilizaremos la lista publicada el 27 de Enero del 2020:

https://www.dof.gob.mx/nota_detalle.php?codigo=5584830&fecha=27/01/2020

Entonces… comencemos.

Lo primero que hay que hacer:

  1. Abrir la línea de comandos, crear la carpeta que contendrá el proyecto e inicializar el proyecto con npm
> mkdir DOF-Scraper
>cd DOF-Scraper
> npm init -y
  1. Instalar el paquete table-scraper con npm
> npm install table-scraper
  1. Abrir el proyecto en tu editor de código favoritos y crear un archivo index.js. Importar los paquetes que utilizaremos:
// Table-scraper nos permitirá extraer la información.const scraper = require("table-scraper");
// Fs nos servirá para crear nuestros archivos de resultados.const fs = require("fs");

  1. Usamos la constante scraper y en específico el método get que recibe un parámetro en formato string (URL)
scrapper.get(
  "https://www.dof.gob.mx/nota_detalle.php?codigo=5584830&fecha=27/01/2020"
);

Como podrán ver, aún no podemos ver ningún resultado porque no estamos haciendo nada con la respuesta de la promesa que contiene el método get.

Captura_de_Pantalla_2021-02-12_a_la(s)_11.52.30.png
  1. Cambiaremos nuestro código para agregar un .then que nos permite manipular la respuesta.
scrapper
  .get(
    "https://www.dof.gob.mx/nota_detalle.php?codigo=5584830&fecha=27/01/2020"
  )
  .then((data) => {
    console.log(data);
    return data;
  });
Captura_de_Pantalla_2021-02-12_a_la(s)_11.55.46.png
  1. Como podrán ver, ahora ya estamos imprimiendo en consola los datos que nos devuelve la función pero al ser mucha la información, es muy difícil analizar la estructura. Es por eso que guardaremos todo este primer resultado en un archivo llamado RAW.json
scrapper
  .get(
    "https://www.dof.gob.mx/nota_detalle.php?codigo=5584830&fecha=27/01/2020"
  )
  .then((data) => {
    fs.writeFile("RAW.json", JSON.stringify(data), function (err, res) {
      if (err) {
        console.log(err);
      }
    });
    return data;
  });
Captura_de_Pantalla_2021-02-12_a_la(s)_11.58.22.png

Ahora, podemos ver toda la estructura del sitio que estamos extrayendo y ver que estamos obteniendo un Json. Analizando el archivo, podremos buscar por patrones y áreas específicas para extraer la información que necesitamos.

  1. Después de un no tan breve análisis, encontramos que en el arreglo 5, línea 7455 del archivo, encontramos los objetos relacionados a la tabla.
Captura_de_Pantalla_2021-02-12_a_la(s)_12.02.16.png
  1. Ahora que conocemos qué parte del archivo contiene la información que necesitamos, procederemos a codificar lo siguiente:
.then((data) => {
    //console.log(data);
    fs.writeFile("RAW.json", JSON.stringify(data), function (err, res) {
      if (err) {
        console.log(err);
      }
    });
    return data;
  })
  .then((data) => {
    let arrayOne = data[5];
    console.log(arrayOne);
  });
Captura_de_Pantalla_2021-02-12_a_la(s)_12.05.13.png

Nos daremos cuenta de que la tabla está partida en arreglos de objetos, por lo que procederemos a hacer la continuidad llamando el siguiente para validar:

.then((data) => {
    let arrayOne = data[6];
    console.log(arrayOne);
  });
Captura_de_Pantalla_2021-02-12_a_la(s)_12.06.37.png

Nos daremos cuenta de que el arreglo 6 no tiene ningún valor definido y por lo tanto, nos devuelve undefined al momento de imprimirlo.

Una vez que seguimos con el siguiente arreglo, nos damos cuenta de que podremos continuar del arreglo 7 al 20 para así obtener la lista completa incluida en la tabla. Utilizaremos el método .concat() para ir concatenando los arreglos:

let concat = arrayOne
      .concat(data[7])
      .concat(data[8])
      .concat(data[9])
      .concat(data[10])
      .concat(data[11])
      .concat(data[12])
      .concat(data[13])
      .concat(data[14])
      .concat(data[15])
      .concat(data[16])
      .concat(data[17])
      .concat(data[18])
      .concat(data[19])
      .concat(data[20]);

console.log(concat)
Captura_de_Pantalla_2021-02-12_a_la(s)_12.10.24.png

Una vez verificamos que efectivamente ya tenemos un json limpio, procederemos a guardarlo en un archivo llamado CLEAN.json:

.then((data) => {
    let arrayOne = data[5];

    let concat = arrayOne
      .concat(data[7])
      .concat(data[8])
      .concat(data[9])
      .concat(data[10])
      .concat(data[11])
      .concat(data[12])
      .concat(data[13])
      .concat(data[14])
      .concat(data[15])
      .concat(data[16])
      .concat(data[17])
      .concat(data[18])
      .concat(data[19])
      .concat(data[20])
      .concat(data[21]);
    console.log(concat);

    fs.writeFile(
      "CLEAN.json",
      JSON.stringify(concat),
      function (err, res) {
        if (err) {
          console.log(err);
        }
      }
    );

    return concat;
  });

Y nuestro archivo se verá así:

Captura_de_Pantalla_2021-02-12_a_la(s)_12.12.36.png

Y ahora tendremos un archivo json almacenado para consumir o almacenar en alguna base de datos como MongoDB y poder generar un script que periódicamente haga la recolección.

Conclusión:

Scrapear es más fácil de lo que parece. En solo 50 líneas de código, obtuvimos información específica de un archivo de más de 5000 líneas. Aprende a hacerlo en la página que quieras con Platzi 💚.

Si quieres seguirme en Github: Rafael Lagunas

Rafael
Rafael
rafalagunas

2497Puntos

hace 3 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
3
11852Puntos

Yo hice un scraper con puppeteer que me trae el texto de los comentarios de cualquier blogpost de Platzi. Lo que no sé es como traer los usuarios, me encantó este post.

3
25268Puntos

Excelente, @rafalagunas, me gustaría hacer la prueba

2
25268Puntos
3 años

Gracias coach por el aporte en verdad

2
27957Puntos

Wow, está genial. Hasta hoy pensaba que sólo se podía hacer con pyhton y que era algo “difícil”. Salgo corriendo a probrarlo.

0
2497Puntos
3 años

¡Qué bueno que te gustó! Para nada, muchas cosas son más fácil de lo que parecen, solo es cuestión de práctica!

2
20949Puntos

Genial otro motivo más para aprender Node.js, cuando leo scrapping pienso en Python ahora tengo más ganas de aprender node

2

Que buen ejemplo y explicación. Desconocía que se podía hacer scrapping con node.js!!
A poner manos a la obra!!

2
141749Puntos

Estimado Rafael que buen aporte, funciona al 100.

0
2497Puntos
3 años

Muchas gracias por tu comentario, saludos!

2
27351Puntos

Muchas gracias @rafalagunas por este ejemplo y explicación, está todo bien claro, y que facil que resulta.

0
2497Puntos
3 años

Gracias por tu comentario Migue! Node.js es muy poderoso. Saludos