Extraer metadatos de una web usando web scrapping
6 minutos de lectura
Índice
Es usual ver sitios donde podemos previsualizar un enlace y obtener información sobre él. Por ejemplo, una aplicación de búsqueda de enlaces o un chat. Para ello, se usa una técnica llamada web scrapping.
Web scrapping
El web scrapping es una técnica que nos permite extraer información de un sitio web, como por ejemplo, el título de una página, el contenido de una página, el autor de una página, etc.
Para realizar web scrapping debemos obtener el html de una web y luego extraer información de él. Para mostrar esto aprenderemos a hacer web scrapping usando NodeJS.
Obtener el html de una web
Para esto debemos hacer una petición a la url para obtener el html, en este caso usaremos el paquete node-fetch para hacer la petición.
1import fetch from 'node-fetch'23// Hacemos la peticion a la url4fetch('https://www.google.com')5 .then((response) => response.text())6 // Y obtenemos el html7 .then((html) => {8 console.log('HTML:', html)9 })
De esta forma, podemos obtener el html de la web que queramos y luego podemos extraer la información que queramos. Pero ¿Que pasa si la web se renderiza en el cliente usando javascript?
Web scrapping en el cliente
Si la web se renderiza en el cliente, podemos usar un navegador sin interfaz gráfica como puppeteer para ejecutar el javascript y obtener el html de la web ya renderizada. Veamos como hacerlo.
1import puppeteer from 'puppeteer'23// Creamos una instancia de puppeteer4const browser = await puppeteer.launch()5// Creamos una nueva página6const page = await browser.newPage()78try {9 // Hacemos la petición a la url10 await page.goto('https://www.google.com')1112 // Obtenemos el html de la página13 const html = await page.content()1415 console.log('HTML:', html)16} catch (error) {17 console.error(error)18} finally {19 // Cerramos la instancia de puppeteer20 await browser.close()21}
Metadatos de una web
Los metadatos de una web se encuentran dentro de la etiqueta <head> de la web. Los más comunes son la etiqueta title y meta.
1<html lang="es">2 <head>3 <meta charset="UTF-8" />4 <meta name="viewport" content="width=device-width, initial-scale=1.0" />56 <title>Soy el título de la web</title>78 <meta name="description" content="Soy la descripción de la web" />9 </head>10 <body>11 <!-- Contenido -->12 </body>13</html>
El title es el título de la web, y el meta contiene un atributo name o property y un atributo content, con el primero especificamos que se trata de la descripción de la web y con el segundo colocamos el valor del metadato.
Puedes ver una lista de etiquetas estándar para metadatos en este enlace.
Adicionalmente a las etiquetas estándar, existen etiquetas no estándar para los metadatos de una web como las usadas en los protocolos Open Graph y Twitter Card. Puedes ver una lista completa de etiquetas no estándar en este enlace.
Open Graph
Open Graph es un protocolo creado originalmente por facebook para darle un estándar a las metadatos de una web. Gracias a este podemos añadir información extra a la web que nos ayuda a compartirla en redes sociales.
Usando nuevamente la etiqueta meta, podemos añadir metadatos a la web usando este protocolo.
1<html lang="es">2 <head>3 <meta charset="UTF-8" />4 <meta name="viewport" content="width=device-width, initial-scale=1.0" />56 <title>Soy el título de la web</title>78 <meta name="description" content="Soy la descripción de la web" />910 <meta property="og:title" content="Soy el título de la web" />11 <meta property="og:type" content="website" />12 <meta property="og:url" content="www.url-de-ejemplo.com" />13 <meta property="og:image" content="www.url-de-ejemplo.com/imagen.png" />14 <meta property="og:image:width" content="500" />15 <meta property="og:image:height" content="500" />16 </head>17 <body>18 <!-- Contenido -->19 </body>20</html>
og:title: Título de la webog:type: Tipo del recurso, web, video, musica, etc.og:url: Url de la webog:image: Imagen de la webog:image:width: Ancho de la imagenog:image:height: Alto de la imagen
Puedes ver una lista completa de los metadatos de Open Graph aquí.
Twitter Card
Twitter Card es un protocolo de twitter para mostrar una previsualización de una web especialmente para twitter y tener una mejor experiencia de usuario.
Podemos hacerlo de igual forma que con Open Graph, usando la etiqueta meta.
1<html lang="es">2 <head>3 <meta charset="UTF-8" />4 <meta name="viewport" content="width=device-width, initial-scale=1.0" />56 <title>Soy el título de la web</title>78 <meta name="description" content="Soy la descripción de la web" />910 <meta property="twitter:title" content="Soy el título de la web" />11 <meta property="twitter:card" content="summary" />12 <meta13 property="twitter:description"14 content="Soy la descripción de la web"15 />16 <meta17 property="twitter:image"18 content="www.url-de-ejemplo.com/imagen.png"19 />20 <meta property="twitter:image:width" content="500" />21 <meta property="twitter:image:height" content="500" />22 <meta property="twitter:url" content="www.url-de-ejemplo.com" />23 </head>24 <body>25 <!-- Contenido -->26 </body>27</html>
twitter:title: Título de la webtwitter:card: Tipo de tarjeta,summary,summary_large_image,app, orplayertwitter:description: Descripción de la webtwitter:image: Imagen de la webtwitter:image:width: Ancho de la imagentwitter:image:height: Alto de la imagentwitter:url: Url de la web
Puedes ver una lista completa de los metadatos de Twitter Card aquí.
Extraer los datos del HTML
Una vez que tenemos el html de la web, podemos extraer los datos que necesitamos. Vamos a usar el paquete cheerio, con este paquete tenemos que cargar el html y luego usar selectores css para obtener las etiquetas y datos que necesitamos.
Primero usamos el metodo .load() para cargar el html y obtener la función $ que nos permite usar los selectores css. Por ejemplo, para obtener el título de la web podemos usar el selector title y luego usar el método text() para obtener el texto.
1import puppeteer from 'puppeteer'2import cheerio from 'cheerio'34// Creamos una instancia de puppeteer5const browser = await puppeteer.launch()6// Creamos una nueva página7const page = await browser.newPage()89try {10 // Hacemos la petición a la url11 await page.goto('https://www.google.com')1213 // Obtenemos el html de la página14 const html = await page.content()1516 // Creamos una instancia de cheerio17 const $ = cheerio.load(html)1819 // Obtenemos el título de la página20 const title = $('title').text()2122 console.log(title) // Google23} catch (error) {24 console.error(error)25} finally {26 // Cerramos la instancia de puppeteer27 await browser.close()28}
Y para obtener la descripción de la página podemos usar el selector meta[name="description"] y luego usar el método attr() para obtener el valor de la etiqueta.
1const description = $('meta[name="description"]').attr('content')
En caso que se haya usado property en vez de name podemos usar el selector meta[property="description"].
1const getDescription = () =>2 $('meta[name="description"]').attr('content') ||3 $('meta[property="description"]').attr('content')
Y de esta manera podemos obtener los datos de los demás metadatos, en este caso añadiremos Open Graph y Twitter Card en remplazo de los metadatos de la web.
1const getMetaTag = (name) =>2 $(`meta[name="${name}"]`).attr('content') ||3 $(`meta[property="${name}"]`).attr('content')45const getMetadata = (name) =>6 getMetaTag(name) || getMetaTag(`og:${name}`) || getMetaTag(`twitter:${name}`)78const getAllMetadata = () => {9 const title = $('title').text() || getMetaTag('title')10 const description = getMetadata('description')11 const image = getMetadata('image')12 const imageWidth = getMetadata('image:width')13 const imageHeight = getMetadata('image:height')14 const url = getMetadata('url')1516 return {17 title,18 description,19 image,20 imageWidth,21 imageHeight,22 url,23 }24}
Conclusión
En este artículo usted ha aprendido como funcionan los metadatos de la web y como extraer los datos de los metadatos de forma automatizada de una web. Espero que haya sido de su agrado y que les sirva de guía.