En este post se va a tratar el Web Scraping. Esta técnica es utilizada para extraer información de páginas web. Es increíblemente útil cuando necesitamos recuperar grandes cantidades de información de diferentes páginas. Debido a que ahorra una gran cantidad de trabajo humano.

En esta ocasión utilizaremos esta técnica para recuperar los títulos de los posts publicados en la página principal de https://techriders.tajamar.es/

También recuperaremos las etiquetas de cada titulo y realizaremos un recuento para ver que temas son más abundantes.

Para realizar esta tarea utilizaremos la librería Cheerio. Una librería desarrollada para facilitar el scraping.

Creación del proyecto y dependencias

Lo primero que debemos hacer es crear un proyecto VUE:

img1

Lo siguiente es movernos al directorio del nuevo proyecto e instalar las librerías que vamos a utilizar. En este caso son Cheerio y axios.

img3
img 4
img5

Ya hemos mencionado Cheerio anteriormente pero no axios. Para los que no conozcan esta librería, esta nos permite realizar peticiones http.

Lo que haremos será conseguir la estructura DOM de la página mediante una petición de axios y mediante Cheerio conseguiremos extraer los titulos y las etiquetas. Comencemos.

Petición HTTP mediante Axios

Lo primero que haremos será crear un nuevo componente donde trabajaremos, para ello haremos click derecho en la carpeta components y seleccionaremos New File. Elegimos el nombre que deseemos y le añadimos la extensión .vue

img7+

En este nuevo archivo abriremos una etiqueta template donde realizaremos el dibujo de la página y una etiqueta script donde diremos como se tiene que comportar la página.

Para evitar errores en la etiqueta template, nos exige tener algo que dibujar en todo momento. En mi caso he puesto una etiqueta h1.

img8

En el script lo primero que haremos será indicarle la manera de exportar el archivo para que luego Vue sea capaz de funcionar correctamente por detrás, yo recomiendo ponerle el mismo nombre que el archivo.

img9

Lo siguiente es indicarle a Vue que vamos a requerir axios y declarar las zonas donde vamos a trabajar en el script.

img10
img11

En siguiente lugar vamos a realizar una petición HTTP de toda la pagina de Tajmar y la vamos a visualizar por consola.

Primero creamos una variable con la ruta que vamos a utilizar

img12

Creamos un método donde realizamos una petición get de axios hacia nuestra url. Posteriormente llamamos a este método dentro de mounted() para que cada vez que se monte la página se ejecute.

img13

Antes de iniciar el proyecto, tenemos que indicarle a Vue que queremos que se nos muestre este componente. Para ello hay que modificar el archivo app.vue de la siguiente manera:

img15

Ahora sí, iniciamos el proyecto para visualizar la estructura de la web de Tajamar.

img14
img16

img17

Como podemos comprobar, nos aparece un error en pantalla que a la vista parece bastante importante y complejo. Bien, ¿qué está ocurriendo y por qué no nos deja hacer la petición?

Muy sencillo, el CORS o Intercambio de Recursos de Origen Cruzado, es lo que está bloqueando nuestra petición. El CORS es una medida de seguridad que bloquea las peticiones HTTP desde un navegador hacia un servidor, justo lo que estamos buscando hacer nosotros. Pero, ¿significa esto que lo que intentamos hacer no es posible? No del todo, hay varias soluciones que podemos llevar a cabo. La primera sería crear nuestro propio servidor para lanzar desde ahí la petición, pero eso es tema para otro post, lo que haremos será utilizar otro servidor para realizar nuestra consulta.

Utilizaremos cors-anywhere.herokuapp.com. Para evitar que se use de manera indefinida el servidor, necesitamos pulsar el botón que aparece en su web. Además está limitado a 50 peticiones por hora. Con esto evitan que se sobreexplote su servidor.

img18

Para indicar en el código que utilizaremos su servidor, cambiaremos la ruta de la petición axios.

img19

Si volvemos a la página podremos ver que ya nos muestra por consola lo que buscábamos

imgbypass

Recuperar información mediante Cheerio

Bien, ya hemos recuperado al estructura de la página, ahora ¿cómo recuperamos los títulos y las etiquetas? Primero tenemos que hacer un trabajo de investigación sobre como está estructurada la web de Tajamar. Pulsamos F12 y buscamos donde están los artículos. Os invito a que lo hagáis vosotros mismos.

img20

Tras rebuscar entre la estructura podemos ver que cada artículo es una etiqueta <article> y todas estas están dentro de una etiqueta <main>. Además, dentro de este <article> encontramos una etiqueta <header> que contiene todo lo que buscamos:

img21
img22

Es importante saber qué estamos buscando y dónde está ubicado para luego poder buscar entre el DOM de manera sencilla.

Volvamos al código. Indicamos que vamos a usar Cheerio del mismo modo que hemos hecho Axios antes.

img23

Guardamos todo el html en una variable.

Guardamos toda la respuesta de la petición en una variable y creamos otra variable $ donde cargaremos el html mediante Cheerio.

         

img24

A partir de aquí es dónde Cheerio entra en acción y saca a relucir todo su potencial. Lo que necesitamos en este momento es recuperar todos los artículos. Bien, lo haremos de la siguiente manera.

img25

Lo que estamos haciendo es que recupere todas las etiquetas <main> del documento que a su vez contengan una etiqueta <article>.

Pero … ¿por qué no buscar simplemente todos los <article>? Bien, esto es un razonamiento lógico, pero hay que tener en cuenta de que puede haber una etiqueta <article> dentro de la página que no corresponda a ningún post. Por eso es importante concretar lo máximo posible en las búsquedas.
Una vez recuperado el artículo necesitamos que recupere su titulo y sus etiquetas.

Crearemos un array donde iremos guardando los títulos y las etiquetas que vayamos recuperando.

img26

Antes de buscar el título repasemos donde está

img27

El titulo está en una etiqueta <a> dentro de un <h2> que a su vez está dentro de un <header> y un <div> que está dentro del header. Una vez localizado lo buscamos en el código y lo guardamos:

img28

Para repasar lo que estamos haciendo, cada <article> que esté dentro de un <main> lo recuperamos como “articulo” y le pedimos que dentro de este artículo busque la siguiente expresión:

img29

El método text() indica que queremos recuperar solamente el texto. Si no llamásemos a este método recuperaríamos más cosas de las que necesitamos.

Hacemos lo mismo para las etiquetas, pero está vez habrá una diferencia. Si nos fijamos en la estructura de la página veremos que en un momento hay 3 etiquetas <li> y nosotros tenemos que acceder a una en específico.

img30

¿Cómo diferenciamos las etiquetas entre sí? Mediante sus clases.

img31

Nótese que para diferenciar entre las etiquetas <li> indicamos la clase con un punto.

Como cada artículo puede tener varias etiquetas hacemos un bucle each de nuevo y recuperamos cada etiqueta y la guardamos en un array al igual que hemos hecho con los títulos.

Visualización de los resultados

Ahora que ya hemos recuperado toda la información que queríamos vamos a mostrarla en la página. Para añadir estilos usaremos la librería Bootstrap , en el archivo index.html añadimos las siguientes líneas .

img32
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>

Las peticiones Http no son instantáneas, por lo que no se mostrarán de manera instantánea en la web. Debido a esto sería conveniente añadir algún tipo de señalización de que la página esta cargando. Para ello creamos una variable booleana que se llame statusTitulos y la inicializamos en falso.

img33

Lo que buscamos es que cuando se dibuje cuando todos los títulos estén cargados, por eso al acabar la petición http cambiaremos esta variable a true.

img34

Ahora sí, lo dibujamos de tal manera que mientras que no haya cargado nos aparezca un gif de cargando. Para ello descargamos el gif que más nos guste y lo guardamos en el proyecto. En mi caso he creado una carpeta de images dentro de la carptea de assets y he guardado ahí el gif.

img36

¡Ya hemos dibujado los títulos de todos los posts!

A continuación vamos a dibujar un botón que muestre un recuento de todas las etiquetas que incluyen estos posts y la cantidad de veces que han aparecido. Para ello crearemos un objeto vacío llamado contador y un booleano llamado statusTags:

img37

Lo siguiente es crear un método que cuente todas las veces que aparece un item de un array y un método que cambie el estado del booleano para saber cuándo hay que dibujarlo:

img38

Ahora dibujamos el botón y lo enlazamos con el método mostrarTags() , que llamará a contarTags() y cambiara statusTags a true para avisar al dibujo de que muestre el recuento de etiquetas.

Vamos con el dibujo:

img39

Pulsamos el botón y podemos ver la nueva funcionalidad

img40

Hasta aquí el post. Espero que hayáis aprendido qué es el concepto de Web Scraping y que os haya picado la curiosidad con esta pequeña demostración.

Autor/a: Jorge Salinero Sánchez
Curso: Desarrollo Web Full Stack, Multicloud y Multiplataforma
Centro: Tajamar
Año académico: 2022-2023

Leave a Comment

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.