Cómo scrapear YouTube como un profesional: Una guía completa

Raluca Penciuc el 20 feb 2023

blog-image

¿Necesita datos de un sitio web, pero las API disponibles no son suficientes? El web scraping es la respuesta que estaba buscando. El web scraping permite extraer datos de un sitio web de forma más completa y flexible.

En este artículo, nos adentraremos en el mundo del web scraping analizando más de cerca cómo hacer scraping de YouTube, una de las plataformas más populares para compartir vídeos. Aunque YouTube proporciona una API para acceder a los datos, el web scraping puede ofrecer una mayor variedad de opciones para extraer datos de los canales de YouTube.

Empezaremos configurando un entorno de desarrollo y cubriendo los requisitos previos para el scraping web, para pasar después al proceso real de cómo scrapear YouTube. En el camino, vamos a proporcionar consejos para mejorar sus habilidades de raspado web y discutir por qué el uso de un raspador profesional puede ser una mejor opción que la construcción de su propio.

Al final de este artículo, dispondrás de los conocimientos y habilidades necesarios para extraer datos de YouTube como un profesional.

Requisitos previos

Lo primero es lo primero, tendrás que asegurarte de que tienes Node.js instalado en tu máquina. Si aún no lo tienes, dirígete al sitio web oficial de Node.j s y sigue las instrucciones para tu sistema operativo específico. Es importante tener en cuenta que debes descargar la versión Long Term Support (LTS) para asegurarte de que tienes una versión estable y compatible.

A continuación, tendrás que instalar el gestor de paquetes de Node.js (NPM). Esto debería venir automáticamente con la instalación de Node.js, pero siempre es bueno volver a comprobarlo.

En cuanto a tu entorno de codificación, siéntete libre de usar el IDE que prefieras. Yo usaré Visual Studio Code en este tutorial porque es flexible y fácil de usar, pero cualquier IDE servirá. Simplemente crea una nueva carpeta para tu proyecto y abre un terminal. Ejecuta el siguiente comando para configurar un nuevo proyecto Node.js:

npm init -y

Esto creará un archivo package.json por defecto para su proyecto. Puede modificar este archivo en cualquier momento para adaptarlo a sus necesidades.

Ahora es el momento de instalar TypeScript y las definiciones de tipo para Node.js. TypeScript es una opción popular entre la comunidad JavaScript debido a su tipado estático opcional, que ayuda a prevenir errores de tipado en tu código. Para instalarlo, ejecuta el siguiente comando:

npm install typescript @types/node --save-dev

Para verificar que la instalación se ha realizado correctamente, puede ejecutar el siguiente comando:

npx tsc --version

Por último, tendrá que crear un archivo de configuración tsconfig.json en la raíz del directorio de su proyecto. Este archivo define las opciones del compilador para tu proyecto. Si quieres saber más sobre este archivo y sus propiedades, consulta la documentación oficial de TypeScript.

Alternativamente, puede copiar y pegar el siguiente código en su archivo tsconfig.json:

{

"compilerOptions": {

"module": "commonjs",

"esModuleInterop": true,

"target": "es2017",

"moduleResolution": "node",

"sourceMap": true,

"outDir": "dist"

},

"lib": ["es2015"]

}

Para el proceso de scraping, utilizaré Puppeteer, una librería de navegador headless para Node.js que permite controlar un navegador web e interactuar con sitios web mediante programación. Para instalar Puppeteer, ejecuta el siguiente comando:

npm install puppeteer

Extracción de datos

Para esta guía, voy a hacer scraping de un canal de YouTube con tutoriales relacionados con DevOps: https://www.youtube.com/@TechWorldwithNana/videos. Los datos que estoy buscando en particular son:

  • el avatar del canal
  • el nombre del canal
  • el asa del canal
  • el número de abonados del canal
  • los títulos de todos los vídeos
  • el número de visionados de todos los vídeos
  • la miniatura de todos los vídeos
  • la URL de todos los vídeos

Incluiré capturas de pantalla para cada sección, y me basaré en selectores CSS para localizar los datos en el DOM. Este es el método más simple y directo, a menos que el sitio web de destino sea conocido por tener una estructura DOM inestable.

Si no conoces los selectores CSS, echa un vistazo a esta completa hoja de trucos que te ayudará a empezar en un abrir y cerrar de ojos.

Comencemos creando una carpeta src y el archivo index.ts donde escribiremos el código. Ahora simplemente abramos un navegador y naveguemos a la URL de destino:

import puppeteer from 'puppeteer';

async function scrapeChannelData(channelUrl: string): Promise<any> {

// Launch Puppeteer

const browser = await puppeteer.launch({

headless: false,

args: ['--start-maximized'],

defaultViewport: null

});

// Create a new page and navigate to the channel URL

const page = await browser.newPage();

await page.goto(channelUrl);

// Close the browser

await browser.close();

}

scrapeChannelData("https://www.youtube.com/@TechWorldwithNana/videos");

Para propósitos de depuración visual abriré el navegador en modo no headless. Si pretendes extender tu caso de uso a gran escala, te recomiendo que eches un vistazo al modo headless.

Para ejecutar el script hay que compilarlo primero, y luego ejecutar el archivo Javascript generado. Para facilitar las cosas, podemos definir un script en el archivo package. json que se encargue de estos dos pasos por nosotros. Simplemente edita la sección de scripts de tu archivo package.j son de la siguiente manera:

"scripts": {

"test": "npx tsc && node dist/index.js"

},

Ahora, todo lo que tienes que hacer para ejecutar tu código es ejecutar el siguiente comando:

npm ejecutar prueba

Desde la primera ejecución, notamos un primer problema: el diálogo de consentimiento de cookies a pantalla completa que nos impide acceder a los datos.

blog-image

Por suerte, está visible en la ventana gráfica, así que podemos utilizar las Herramientas de desarrollo para encontrar su identificador y hacer clic en él.

blog-image

También añadimos un tiempo de espera extra para dejar que se complete la navegación. El código tendrá este aspecto:

await page.waitForSelector('botón[aria-label="Aceptar todo"]')

await page.click('botón[aria-label="Aceptar todo"]')

await page.waitForTimeout(10 * 1000)

Información del canal

En la siguiente captura de pantalla podemos ver resaltadas las secciones que contienen los datos del canal que queremos extraer.

blog-image

Una buena regla para facilitar la localización de los elementos HTML es elegir selectores CSS únicos. Por ejemplo, para extraer el avatar del canal, elegiré el elemento HTML personalizado yt-img-shadow con el id avatar. Luego extraeré el atributo src de su elemento hijo img .

const channelAvatar = await page.evaluate(() => {

const el = document.querySelector('yt-img-shadow#avatar > img');

return el ? el.getAttribute('src') : null;

});

console.log(canalAvatar)

Para el nombre del canal, tenemos el contenido de texto del elemento yt-formatted-string con el texto id.

const channelName = await page.evaluate(() => {

const el = document.querySelector('yt-formatted-string#text');

return el ? el.textContent : null;

});

console.log(channelName)

Para obtener el asa del canal, localizaremos el elemento yt-formatted-string con el id channel-handle y extraeremos su contenido de texto.

const channelHandle = await page.evaluate(() => {

const el = document.querySelector('yt-formatted-string#channel-handle');

return el ? el.textContent : null;

});

console.log(channelHandle)

Y finalmente, para el número de suscriptores del canal, sólo tenemos que acceder al elemento yt-formatted-string con el id subscriber-count y obtener su contenido de texto.

const subscriberCount = await page.evaluate(() => {

const el = document.querySelector('yt-formatted-string#subscriber-count');

return el ? el.textContent : null;

});

console.log(subscriberCount)

Al ejecutar el script de nuevo, debería ver la siguiente salida:

https://yt3.googleusercontent.com/kXyR8Aa32KXnZWVdkAFUYK5utM752kSJPHGtYiJ4ev6BmdFHi-dl1EFbI3TogmHBjszwc7m2=s176-c-k-c0x00ffffff-no-rj

TechWorld with Nana

@TechWorldwithNana

709K subscribers

Datos de vídeo

Pasando a los datos del vídeo, también he resaltado las secciones relevantes del documento HTML. Aquí, debemos extraer una lista de elementos, por lo que miramos primero los contenedores padre y luego iteramos a través de cada uno de ellos.

blog-image

Seguimos el mismo enfoque de la sección anterior: elegir algunos selectores CSS únicos para localizar los datos que necesitamos, centrándonos en sus ids. El código debería parecerse a esto:

const videos = await page.evaluate(() => {

const videosEls = Array.from(document.querySelectorAll('div#dismissible'))

return videosEls.map(video => {

const titleEl = video.querySelector('yt-formatted-string#video-title');

const viewsEl = video.querySelector('div#metadata-line > span');

const thumbnailEl = video.querySelector('yt-image.ytd-thumbnail > img');

const locationEl = video.querySelector('a#thumbnail');

return {

title: titleEl ? titleEl.textContent : null,

views: viewsEl ? viewsEl.textContent : null,

thumbnail: thumbnailEl ? thumbnailEl.getAttribute('src') : null,

location: locationEl ? locationEl.getAttribute('href') : null

}

})

})

console.log(videos)

Cuando ejecutes el código, la salida debería ser una lista de objetos Javascript. Cada uno de ellos debe contener el título, el número de visualizaciones, la miniatura y la ubicación de cada elemento de vídeo en la página.

Sin embargo, notarás que después de un punto, tu lista empieza a parecerse a esto:

{

title: 'GitLab CI/CD Full Course released - CI/CD with Docker | K8s | Microservices!',

views: '114K views',

thumbnail: null,

location: '/watch?v=F7WMRXLUQRM'

},

{

title: 'Kubernetes Security Best Practices you need to know | THE Guide for securing your K8s cluster!',

views: '103K views',

thumbnail: null,

location: '/watch?v=oBf5lrmquYI'

},

{

title: 'How I learn new technologies as a DevOps Engineer (without being overwhelmed)',

views: '366K views',

thumbnail: null,

location: '/watch?v=Cthla7KqU04'

},

{

title: 'Automate your Multi-Stage Continuous Delivery and Operations | with Keptn',

views: '59K views',

thumbnail: null,

location: '/watch?v=3EEZmSwMXp8'

},

Aunque los elementos de vídeo siguen teniendo una miniatura y el selector CSS no ha cambiado, el valor extraído es nulo. Esto suele ocurrir cuando un sitio web implementa la carga perezosa, lo que significa que el resto de la lista se carga a medida que se desplaza hasta el final de la página.

Para resolver este problema, simplemente tenemos que ordenar a nuestro script que se desplace hacia abajo en la página del canal.

async function autoScroll(page: any, scroll_number: number): Promise<any> {

await page.evaluate(async (scroll_number: number) => {

await new Promise((resolve) => {

let totalHeight = 0;

const timer = setInterval(() => {

const scrollHeight = window.innerHeight * scroll_number;

window.scrollBy(0, window.innerHeight);

totalHeight += window.innerHeight;

if (totalHeight > scrollHeight) {

clearInterval(timer);

resolve(true);

}

}, 1000);

});

}, scroll_number);

}

Esta función toma como parámetros nuestra página abierta y un número de movimientos de desplazamiento. Luego intenta desplazarse la distancia igual a la altura de la ventana tantas veces como le indique el parámetro número_desplazamiento. Estos movimientos se realizan cada 1 segundo.

Ahora sólo tiene que llamar a la función anterior al fragmento de código que extrae la lista de vídeos.

await autoScroll(page, 10)

await page.waitForTimeout(2 * 1000)

He añadido un tiempo de espera adicional de 2 segundos para que el sitio web tenga tiempo de cargar completamente los últimos elementos de la lista. Ejecutando de nuevo el script, podrás ver primero cómo se producen los movimientos de desplazamiento y después que todos los elementos de la lista tienen un valor de miniatura.

Evitar el bloqueo

Aunque la guía hasta este punto parecía no suponer ningún esfuerzo, existen múltiples retos con los que se suelen encontrar los web scrapers. YouTube en particular implementa muchas técnicas antibot para evitar que scripts automatizados extraigan sus datos.

Algunas de estas técnicas son:

  • CAPTCHAs: resolver CAPTCHAs puede llevar mucho tiempo y ser difícil para un scraper, lo que puede servir como elemento disuasorio para los bots.
  • Retos JavaScript: pueden incluir tareas como resolver problemas matemáticos, completar un CAPTCHA o encontrar un elemento específico en la página. Un bot que no pueda completar el desafío será detectado y potencialmente bloqueado.
  • Comprobaciones de User-Agent: YouTube puede comprobar la cadena de agente de usuario de las solicitudes entrantes para ver si proceden de un navegador o de un scraper. Si la cadena de agente de usuario no se reconoce como un navegador válido, la solicitud puede bloquearse.
  • Bloqueo de IP: YouTube puede bloquear las solicitudes procedentes de determinadas direcciones IP que se sabe que están asociadas a bots o a actividades de scraping.
  • Honeypots: YouTube puede utilizar honeypots, que son elementos ocultos en la página que sólo son visibles para los bots. Si se detecta a un bot interactuando con un honeypot, puede ser identificado y bloqueado.

Tratar cada uno de estos problemas puede aumentar significativamente la complejidad y el coste del código de su scraper. Aquí es donde las API de raspado desempeñan un papel importante, ya que se encargan de estos problemas por defecto y están disponibles a un precio menor.

WebScrapingAPI es un ejemplo de este tipo de servicio. Ofrece potentes funciones para evitar las técnicas de detección de bots y extraer con precisión los datos que necesitas.

Podemos probar rápidamente el uso de WebScrapingAPI instalando el SDK de Node.js en nuestro pequeño proyecto:

npm i webscrapingapi

Ahora visita la página de inicio para registrar una cuenta, que te proporcionará automáticamente tu clave API y una prueba gratuita. La clave API se encuentra en el panel de control y la utilizarás para autenticar tus solicitudes a la API:

blog-image

Y eso es todo, ¡ya puedes empezar a codificar!

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage(target_url: string) {

const api_params = {

'render_js': 1,

'proxy_type': 'datacenter',

'country': 'us',

'timeout': 60000,

'js_instructions': JSON.stringify([

{

action: "click",

selector: 'button[aria-label="Accept all"]',

timeout: 10000

}

]),

'extract_rules': JSON.stringify({

avatar: {

selector: "yt-img-shadow#avatar > img",

output: "@src",

},

name: {

selector: "yt-formatted-string#text",

output: "text",

},

handle: {

selector: "yt-formatted-string#channel-handle",

output: "text",

},

subscribers: {

selector: "yt-formatted-string#subscriber-count",

output: "text",

},

videoTitles: {

selector: "yt-formatted-string#video-title",

output: "text",

all: "1"

},

videoViews: {

selector: "div#metadata-line > span",

output: "text",

all: "1"

},

videoThumbnails: {

selector: "yt-image.ytd-thumbnail > img",

output: "@src",

all: "1"

},

videoLocations: {

selector: "a#thumbnail",

output: "@href",

all: "1"

},

})

}

const response = await client.get(target_url, api_params);

if (response.success) {

console.log(response.response.data);

} else {

console.log(response.error.response.data);

}

}

exampleUsage("https://www.youtube.com/@TechWorldwithNana/videos");

Trasladamos el algoritmo y los selectores CSS descritos anteriormente a la API. El parámetro "js_instructions" se encargará de la ventana de cookies, pulsando el botón "Accept All". Por último, el parámetro "extract_rules" se encargará de la extracción de datos.

const scroll_number = 10

let scroll_index = 0

for (let i = 0; i < scroll_number; i++) {

const js_instructions_obj = JSON.parse(api_params.js_instructions)

js_instructions_obj.push({

action: "scrollTo",

selector: `ytd-rich-grid-row.ytd-rich-grid-renderer:nth-child(${scroll_index + 3})`,

block: "end",

timeout: 1000

})

api_params.js_instructions = JSON.stringify(js_instructions_obj)

scroll_index += 3

}

A continuación, justo antes de enviar la solicitud, recuerde ajustar también la lógica de desplazamiento. Esta será ligeramente diferente, ya que ordenamos a la API que se desplace hasta la tercera fila de vídeos 10 veces.

Conclusión

En este artículo, hemos explorado el apasionante campo del web scraping y hemos aprendido a extraer datos de YouTube utilizando Node.js y Puppeteer. Hemos cubierto la configuración necesaria para el web scraping, así como el proceso de extracción de datos de los canales de YouTube.

El web scraping puede ser una herramienta increíblemente útil para acceder a datos de sitios web. Sin embargo, es importante tener en cuenta los diversos retos y consideraciones que conlleva. Estos pueden incluir CAPTCHAs, contenido dinámico, limitación de velocidad o cambios en el sitio web.

Si estás pensando en raspar datos de YouTube o de cualquier otro sitio web, es esencial sopesar los pros y los contras y determinar si el web scraping es la mejor solución para tus necesidades. En algunos casos, utilizar una API o comprar datos a una fuente de confianza puede ser una opción más adecuada que el scraping.

Independientemente del método que elijas, es fundamental respetar las condiciones del servicio y las leyes de derechos de autor que se aplican a los datos a los que accedes. Y si decides extraer datos de YouTube, recuerda utilizar un scraper profesional para asegurarte de que obtienes datos precisos y actualizados de forma segura y eficaz.

Espero que este artículo te haya servido de ayuda a la hora de embarcarte en tu viaje para aprender sobre web scraping y cómo scrapear datos de YouTube.

Noticias y actualidad

Manténgase al día de las últimas guías y noticias sobre raspado web suscribiéndose a nuestro boletín.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artículos relacionados

miniatura
GuíasSERP Scraping API - Guía de inicio

Recopile sin esfuerzo datos en tiempo real de los motores de búsqueda mediante la API SERP Scraping. Mejore el análisis de mercado, el SEO y la investigación temática con facilidad. ¡Empiece hoy mismo!

WebscrapingAPI
avatar de autor
WebscrapingAPI
7 min leer
miniatura
GuíasCómo raspar datos de productos de Amazon: Guía completa de mejores prácticas y herramientas

Explore las complejidades del scraping de datos de productos de Amazon con nuestra guía en profundidad. Desde las mejores prácticas y herramientas como Amazon Scraper API hasta las consideraciones legales, aprenda a superar los desafíos, eludir los CAPTCHA y extraer información valiosa de forma eficiente.

Suciu Dan
avatar de autor
Suciu Dan
15 minutos de lectura
miniatura
Casos prácticosUtilizando Web Scraping para Datos Alternativos en Finanzas: Guía completa para inversores

Explore el poder transformador del web scraping en el sector financiero. Desde datos de productos hasta análisis de opiniones, esta guía ofrece información sobre los distintos tipos de datos web disponibles para tomar decisiones de inversión.

Mihnea-Octavian Manolache
avatar de autor
Mihnea-Octavian Manolache
13 min leer