Volver al blog
Guías
Raluca PenciucLast updated on May 8, 202621 min read

Cómo scrapear YouTube con Python en 2026

Cómo scrapear YouTube con Python en 2026
En resumen: esta es una guía de 2026 sobre cómo extraer datos de YouTube con Python. Elegirás el método adecuado (Data API v3, yt-dlp, /youtubei/v1/ o un rastreador gestionado) mediante una matriz de decisión, y luego ejecutarás código para metadatos de vídeo, comentarios, canales, búsquedas, Shorts y transcripciones, con una sección de producción sobre proxies, encabezados y retardo 429 para que no te bloqueen.

Introducción

Si alguna vez te has topado con el límite de cuota de la API de datos de YouTube v3 en medio de una sesión de investigación, ya sabes por qué los desarrolladores aprenden a extraer datos de YouTube directamente. La API oficial es clara y está bien documentada, pero su presupuesto diario de 10 000 unidades se agota rápidamente en cuanto empiezas a search.list o extraer hilos de comentarios profundos. El scraping web de YouTube llena ese vacío, y los datos son mucho más ricos que los que expone la API: árboles de comentarios completos, transcripciones, etiquetas, recuentos de «Me gusta», Shorts y catálogos de vídeos de los canales.

Esta guía está pensada para desarrolladores de Python, ingenieros de datos, analistas de crecimiento y SEO, y profesionales de IA/ML que necesitan datos masivos de YouTube para análisis, pipelines RAG o investigación de la competencia. Pasaremos de una introducción rápida sin clave API a extracciones de nivel de producción utilizando yt-dlp, /youtubei/v1/ y una API de scraping gestionada. Cada sección incluye código Python ejecutable, y los ejemplos asumen Python 3.11 o una versión más reciente.

Al final, tendrás una matriz clara de selección de métodos, código funcional para las siete tareas de scraping de YouTube más comunes, una capa antibloqueo que resiste el tráfico del mundo real y una lista de verificación legal que evitará que tu proyecto sea cerrado. Empecemos.

Por qué merece la pena extraer datos de YouTube en 2026

YouTube es el segundo motor de búsqueda más grande del planeta y el mayor archivo de comentarios en vídeo de larga duración en cualquier idioma. Eso lo convierte en una mina de oro para tres tareas que la API de datos oficial nunca fue diseñada para gestionar a gran escala.

Análisis de creadores y de la competencia. Extraer todo el historial de subidas de un competidor con recuentos de visualizaciones, duraciones, etiquetas y cadencia de publicación revela qué formatos funcionan realmente, no solo cuáles muestra hoy el algoritmo de YouTube.

Sentimiento de la audiencia e investigación de productos. Los hilos de comentarios bajo reseñas de productos, tutoriales y unboxings son algunos de los textos generados por los usuarios más sinceros de la web abierta. Los modelos de sentimiento entrenados con comentarios de YouTube tienden a generalizarse bien porque la redacción es coloquial y subjetiva.

Aportaciones de SEO, tendencias y RAG. Las transcripciones, junto con los títulos y los comentarios más destacados, te proporcionan un contenido de texto limpio que un proceso de generación aumentada por recuperación puede fragmentar e integrar sin necesidad de extraer el archivo de vídeo en sí. Ese es el caso de uso que impulsó a la mayoría de los equipos a pasar de la API de datos a aprender a extraer datos de YouTube mediante programación en primer lugar.

Sea cual sea el objetivo, considera este artículo como un manual de estrategias método por método, en lugar de un tutorial sobre una única herramienta. Cada tarea requiere herramientas diferentes.

Cómo extraer datos de YouTube: elige el método adecuado antes de escribir código

Hoy en día hay cuatro formas realistas de aprender a extraer datos de YouTube en Python, y una elección equivocada agotará tu cuota, hará que te bloqueen o, simplemente, no te devolverá el campo que necesitas. Elige primero, programa después.

Método

Cuota / modelo de coste

Riqueza de datos

Riesgo de bloqueo por bots

La mejor opción

API de datos de YouTube v3

Cuota diaria fija (por defecto 10 000 unidades, ver documentación de Google)

Estructurada pero limitada: sin hilos de comentarios, estadísticas limitadas

Ninguna (oficial)

Único, estructurado, bajo volumen

yt-dlp

Sin cuota, con limitación automática

Muy completo: más de 100 campos, comentarios, suscripciones, formatos

Medio (firmado por cookies de YouTube)

Extracción profunda y transcripciones por vídeo

Oculto /youtubei/v1/ puntos finales

Sin cuota

El mismo JSON que consume la interfaz de YouTube

Alto a gran escala (requiere proxies + encabezados)

Búsqueda, paginación de canales, comentarios en profundidad

API de scraping gestionada

Por solicitud exitosa

Sea lo que sea lo que devuelva la página, se renderiza por completo

Gestionado por el proveedor

Escala de producción, gestión anti-bot

Dos patrones se repiten en las últimas tres filas: extraer JSON incrustado en etiquetas de script (ytInitialPlayerResponse, ytInitialData) y replicar las llamadas XHR internas que dispara la SPA de YouTube. Ambas devuelven datos estructurados sin necesidad de iniciar un navegador sin interfaz gráfica, lo que mantiene las solicitudes rápidas y económicas. Recurre a un navegador real solo cuando tengas que iniciar sesión o activar un evento impulsado por la interfaz de usuario.

Si aún te estás preguntando cuál elegir antes de escribir el código, las dos subsecciones siguientes te ayudarán a decidir.

Cuándo basta con la API de datos de YouTube v3

La API de datos v3 es la opción más segura para obtener datos limpios y estructurados en pequeños volúmenes. Devuelve ID canónicos, estadísticas oficiales y esquemas estables, y te mantienes al margen de los Términos de servicio de YouTube por diseño.

El inconveniente está en el cálculo de las unidades. Según la documentación de la API de datos de YouTube, cada proyecto comienza con una cuota diaria predeterminada (actualmente alrededor de 10 000 unidades, pero compruébalo en la Consola de Google Cloud, ya que Google la ajusta). Una videos.list llamada cuesta aproximadamente 1 unidad, mientras que una search.list llamada cuesta aproximadamente 100 unidades, por lo que una sola sesión de búsqueda profunda puede agotar el presupuesto de todo un día en cuestión de minutos. Vuelve a confirmar los costes exactos por unidad en la documentación oficial antes de comprometerte con la opción «solo API».

Utiliza la API cuando necesites unos pocos miles de registros de vídeo al día con campos estables y sin exposición a los bots. Para cualquier cosa que supere eso, recurre al scraping.

Cuándo debes pasar al web scraping

Cambia al web scraping en cuanto se cumpla cualquiera de estas condiciones:

  • Necesitas metadatos masivos de miles de vídeos al día.
  • Necesitas hilos de comentarios completos con respuestas, orden de clasificación o el nombre de usuario del autor del comentario.
  • Necesitas transcripciones o subtítulos generados automáticamente mediante programación.
  • Necesitas que los YouTube Shorts se filtren claramente de los resultados de búsqueda.
  • Necesitas catálogos de vídeos de canales más completos de lo que te ofrece la respuesta paginada de la API.
  • Necesitas cualquier campo que simplemente no esté expuesto por la API (las etiquetas de la mayoría de los vídeos, por ejemplo).

La matriz de decisión de esta página es, intencionadamente, la primera respuesta para cualquiera que aprenda a extraer datos de YouTube en 2026, porque elegir la herramienta equivocada es el error más costoso que puedes cometer en esta plataforma.

Requisitos previos y configuración del proyecto

Antes de ejecutar cualquiera de los códigos de scraping de YouTube que aparecen a continuación, configura un proyecto limpio de Python 3.11+ para que las dependencias no entren en conflicto con tus otras herramientas.

mkdir youtube-scraper && cd youtube-scraper
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install --upgrade yt-dlp requests beautifulsoup4 parsel \
            jsonpath-ng youtube-transcript-api

Esa única instalación cubre todo lo que se incluye en esta guía:

  • yt-dlp para metadatos de vídeo, comentarios y subtítulos.
  • requests + BeautifulSoup4 para páginas HTML y el <script> truco de la etiqueta.
  • parsel para CSS/XPath cuando BeautifulSoup resulte demasiado prolijo.
  • jsonpath-ng para recorrer respuestas profundamente anidadas /youtubei/v1/ respuestas.
  • youtube-transcript-api como atajo de transcripción en una sola llamada.

Dos términos que verás a lo largo del texto. El scraping de datos ocultos extrae un blob JSON de una <script> etiqueta del HTML de la página; en YouTube, el ejemplo canónico es ytInitialPlayerResponse. El scraping de API oculta replica las llamadas XHR/fetch internas que realiza la aplicación de página única de YouTube, accediendo /youtubei/v1/ puntos finales directamente para recibir JSON estructurado. Ambos evitan el DOM renderizado, lo que hace que los rastreadores sean más rápidos y menos frágiles que el análisis del diseño visual. Con estos conceptos en mente, la guía de inicio rápido sin clave API está a solo unas líneas de distancia.

Inicio rápido: obtener el título, las visualizaciones y el canal sin clave API

La forma más rápida de obtener resultados sin clave en el scraping web de YouTube es recuperar una página de visualización, extraer el ytInitialPlayerResponse y leer de él lo que necesites. Sin proyecto API, sin OAuth, sin navegador sin interfaz gráfica.

import json, re, requests

VIDEO_URL = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) '
                  'AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/124.0 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.9',
}

html = requests.get(VIDEO_URL, headers=HEADERS, timeout=15).text
match = re.search(r'ytInitialPlayerResponse\s*=\s*(\{.+?\})\s*;', html)
data = json.loads(match.group(1))

details = data['videoDetails']
print(details['title'])
print(details['author'])
print(details['viewCount'])
print(details['lengthSeconds'])

Ese fragmento de código es aproximadamente el 90 % de lo que la mayoría de los lectores vinieron a buscar aquí: una respuesta que funcione sobre cómo extraer metadatos de vídeos de YouTube sin una clave API. La expresión regular está dirigida a la línea de asignación que YouTube ha utilizado durante años, pero considérala un objetivo en movimiento. Si una solicitud devuelve un resultado en blanco o la expresión regular falla, es probable que YouTube te haya redirigido con una cookie de consentimiento (más sobre eso más adelante), o que haya modificado el marcado que rodea la etiqueta script. Reforzamos esto en la sección de antibloqueo.

Extraer metadatos completos de vídeos con yt-dlp

ytInitialPlayerResponse es ideal para algunos campos. Para los datos más específicos (formatos, número de «me gusta», fecha de subida, todas las etiquetas, subtítulos automáticos, lista de capítulos), utiliza yt-dlp. Se trata de una bifurcación mantenida por la comunidad de youtube-dl con un conjunto de funciones más amplio y actualizaciones activas; consulta el repositorio de GitHub de yt-dlp para ver las opciones y los campos disponibles antes de confiar en ningún nombre de campo específico.

yt-dlp's extract_info(download=False) devuelve un diccionario Python plano con un gran número de campos que abarcan el título, el recuento de visualizaciones y «me gusta», la fecha de subida, las etiquetas, las miniaturas y todos los formatos multimedia disponibles. El recuento exacto de campos varía de una versión a otra, así que no codifiques expectativas de forma rígida.

import json
import yt_dlp

VIDEO_URL = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'

ydl_opts = {
    'quiet': True,
    'skip_download': True,
    # 'cookiesfrombrowser': ('chrome',),  # for age-gated content
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(VIDEO_URL, download=False)

keys_we_care_about = (
    'id', 'title', 'channel', 'channel_id', 'upload_date',
    'duration', 'view_count', 'like_count', 'tags',
    'categories', 'description',
)
flat = {k: info.get(k) for k in keys_we_care_about}
print(json.dumps(flat, indent=2, ensure_ascii=False))

Dos indicadores que utilizarás a menudo:

  • 'cookiesfrombrowser': ('chrome',) permite a yt-dlp reutilizar la sesión de tu navegador para vídeos con restricción de edad, bloqueados por región o exclusivos para miembros.
  • 'extract_flat': 'in_playlist' omite las llamadas a metadatos por vídeo cuando solo necesitas los ID de los vídeos de la lista de reproducción.

Para conservar el resultado, exporta el diccionario a JSON Lines (un registro por línea) para que puedas añadir nuevos vídeos sin reescribir el archivo:

with open('videos.jsonl', 'a', encoding='utf-8') as f:
    f.write(json.dumps(flat, ensure_ascii=False) + '\n')

yt-dlp se auto-limita y gestiona muchos casos extremos (transmisiones en directo, estrenos, contenido exclusivo para miembros) sin código adicional, por lo que es la herramienta predeterminada cuando los equipos preguntan cómo extraer datos de vídeos de YouTube mediante programación sin tener que implementar una pila completa de medidas anti-bot.

Extraer comentarios de YouTube a gran escala

Los comentarios son la razón más común por la que los equipos superan los límites de la API de datos. El commentThreads punto de conexión tiene un límite de cuota elevado y pocas respuestas, mientras que yt-dlp extrae una profundidad configurable en una sola llamada. Aquí es donde scrape YouTube comments Python se pone interesante.

import yt_dlp

VIDEO_URL = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'

ydl_opts = {
    'quiet': True,
    'skip_download': True,
    'getcomments': True,
    'extractor_args': {
        'youtube': {
            'comment_sort': ['top'],   # or 'new'
            'max_comments': ['200', '50', '10', '0'],  # total, per-thread, replies-per-thread, child-replies
        }
    },
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(VIDEO_URL, download=False)

for c in info.get('comments', [])[:5]:
    print(c['author'], '|', c['text'][:120])

Tres cosas que hay que saber sobre esa respuesta:

  • La lista es plana. Las respuestas aparecen con un parent campo que apunta a su ID de comentario raíz, por lo que hay que reconstruir los hilos en el posprocesamiento.
  • El orden de clasificación es el mejor posible. comment_sort solo lo solicita; YouTube sirve lo que tiene almacenado en caché.
  • Para una paginación profunda más allá de lo que max_comments devuelve de forma fiable, pasa al /youtubei/v1/next punto final con el commentContinuationToken extraído de la página de visualización. Envía el token, obtén una nueva continuación y repite hasta que la respuesta deje de devolverla.

Ese enfoque de API oculta es más complicado de mantener porque YouTube cambia la estructura de la respuesta periódicamente, pero es la única forma de llegar al recuento de comentarios de cola larga en los vídeos virales. Planea envolverlo en una capa de reintentos compatible con el 429 (que se tratará más adelante) antes de dejarlo funcionar sin supervisión.

Rastrear páginas de canales de YouTube y vídeos subidos

Hay dos tareas que se engloban en el «raspado de canales»: extraer los campos del perfil del canal (nombre, descripción, enlaces, país, número de suscriptores si es público) y recorrer la pestaña de vídeos de principio a fin.

Ruta 1: analiza la sección «Acerca de» del canal. Es HTML, por lo que un requests paso con BeautifulSoup /@channelhandle/about te proporciona lo básico. Los pocos campos que YouTube oculta tras un cuadro de diálogo controlado por JS (enlaces, correo electrónico de la empresa) siguen incrustados en el mismo ytInitialData bloque de script que usaste para la guía rápida.

import json, re, requests
from bs4 import BeautifulSoup

URL = 'https://www.youtube.com/@GoogleDevelopers/about'
html = requests.get(URL, headers={'Accept-Language': 'en-US,en;q=0.9'}).text

soup = BeautifulSoup(html, 'html.parser')
title_tag = soup.find('meta', attrs={'name': 'title'})
channel_title = title_tag['content'] if title_tag else None

init = re.search(r'var ytInitialData\s*=\s*(\{.+?\});', html).group(1)
data = json.loads(init)
# data now contains description, links, subscriberCountText, etc., nested under 'header' / 'metadata'

Ruta 2: paginar la pestaña de vídeos /youtubei/v1/browse. El primer lote de vídeos llega en ytInitialData, pero todo lo que viene después se envía a través de tokens de continuación. Extrae el primer token del blob inicial y, a continuación, envíalo de vuelta a la API oculta para obtener la página siguiente.

import requests

YT_API = 'https://www.youtube.com/youtubei/v1/browse'
CLIENT = {'clientName': 'WEB', 'clientVersion': '2.20240101.00.00'}

def fetch_videos_page(continuation_token: str) -> dict:
    payload = {
        'context': {'client': CLIENT},
        'continuation': continuation_token,
    }
    r = requests.post(YT_API, params={'prettyPrint': 'false'}, json=payload, timeout=20)
    r.raise_for_status()
    return r.json()

def walk(continuation_token: str, max_pages: int = 5):
    for _ in range(max_pages):
        data = fetch_videos_page(continuation_token)
        # videos under: onResponseReceivedActions[*].appendContinuationItemsAction.continuationItems[*]
        yield data
        next_tokens = [
            item['continuationItemRenderer']['continuationEndpoint']['continuationCommand']['token']
            for action in data.get('onResponseReceivedActions', [])
            for item in action.get('appendContinuationItemsAction', {}).get('continuationItems', [])
            if 'continuationItemRenderer' in item
        ]
        if not next_tokens:
            return
        continuation_token = next_tokens[0]

Ese patrón de continuación es el mismo que utilizan los resultados de búsqueda y los comentarios, por lo que vale la pena familiarizarse con él una vez. Utiliza jsonpath-ng o jmespath para mantener legibles las expresiones de ruta en lugar de encadenar .get() llamadas. Para recuperaciones de historiales profundos, ejecuta el bucle detrás de un grupo de proxies, ya que acceder /youtubei/v1/browse rápidamente desde una misma IP es la forma más rápida de activar el limitador de velocidad de YouTube.

Extraer los resultados de búsqueda de YouTube

La búsqueda en YouTube es la superficie más difícil de mantener en funcionamiento a largo plazo, ya que el diseño de la SERP cambia y la API requiere un encabezado clientVersion encabezado. Replica el XHR privado que puedes observar en DevTools (pestaña Red, filtra por youtubei) y tendrás un rastreador estable.

import requests
from jsonpath_ng.ext import parse

YT_SEARCH = 'https://www.youtube.com/youtubei/v1/search'
CONTEXT = {'client': {'clientName': 'WEB', 'clientVersion': '2.20240101.00.00'}}

def search_youtube(query: str) -> list[dict]:
    payload = {'context': CONTEXT, 'query': query}
    r = requests.post(YT_SEARCH, json=payload, timeout=20)
    r.raise_for_status()
    data = r.json()

    expr = parse('$..videoRenderer')
    results = []
    for m in expr.find(data):
        v = m.value
        results.append({
            'id': v.get('videoId'),
            'title': v['title']['runs'][0]['text'],
            'channel': v.get('ownerText', {}).get('runs', [{}])[0].get('text'),
            'views_text': v.get('viewCountText', {}).get('simpleText'),
        })
    return results

for hit in search_youtube('python web scraping')[:5]:
    print(hit)

Algunas notas de producción que te ahorrarán tiempo de depuración:

  • Los clientVersion valor varía. Obtén uno nuevo de vez en cuando de https://www.youtube.com/sw.js_data o inspeccionando cualquier página de seguimiento; si se fija una versión obsoleta, al final se obtienen cargas útiles vacías.
  • La paginación utiliza el mismo patrón de token de continuación que los vídeos del canal, solo que se obtiene de la propia respuesta de búsqueda.
  • videoRenderer es el tipo de resultado más común, pero la búsqueda también devuelve channelRenderer, playlistRenderery reelItemRenderer (Shorts), así que filtra explícitamente según la superficie que desees.

Si mantienes una herramienta de larga duración que aprende a extraer resultados de búsqueda de YouTube en producción, prepárate para actualizar la lógica de recorrido de JSON cada pocos meses. La estructura del punto final es lo suficientemente estable como para confiar en ella, pero los nombres de los campos dentro de los renderizadores sí cambian.

Extraer YouTube Shorts

Los Shorts de YouTube utilizan una interfaz de reproducción diferente a la de los vídeos normales, pero el flujo de metadatos es idéntico. Cada Short sigue teniendo una URL de visualización con el formato https://www.youtube.com/shorts/<videoId> que se resuelve en una página de visualización normal del lado del servidor, y la página sigue incrustando ytInitialPlayerResponse. Eso significa que todo lo de la sección de inicio rápido funciona en los Shorts sin cambios en el código.

import json, re, requests
URL = 'https://www.youtube.com/shorts/<videoId>'
html = requests.get(URL, headers={'Accept-Language': 'en-US'}).text
data = json.loads(re.search(r'ytInitialPlayerResponse\s*=\s*(\{.+?\})\s*;', html).group(1))
print(data['videoDetails']['title'], data['videoDetails']['viewCount'])

Para aislar los Shorts dentro de los resultados de búsqueda, filtra por el reelItemRenderer (o shortsLockupViewModel en respuestas más recientes) en lugar de videoRenderer al recorrer el JSON. Para mostrar los Shorts de un creador, pulsa la tecla /shorts del canal mediante el mismo /youtubei/v1/browse bucle de continuación que usaste para la pestaña de vídeos normales, solo que con el browseId de Shorts del canal. Esto cubre la mayor parte de lo que la gente quiere decir cuando pregunta cómo extraer Shorts de YouTube a gran escala sin un emulador de aplicaciones móviles personalizado.

Extraer transcripciones y subtítulos de YouTube

Las transcripciones son la carga de texto de mayor valor en la plataforma y la más frágil de extraer. Hay dos vías prácticas.

Vía A: yt-dlp con writesubtitles y writeautomaticsub. Esta es la opción más fiable porque yt-dlp genera la json3 URL firmada. YouTube ya no ofrece transcripciones de forma fiable desde una api/timedtext?lang=en&v=ID sin parámetros firmados, por lo que se recomienda generar la URL mediante un extractor. Comprueba la fuente actual de yt-dlp si el comportamiento cambia.

import yt_dlp, requests

VIDEO_URL = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
ydl_opts = {
    'quiet': True,
    'skip_download': True,
    'writesubtitles': True,
    'writeautomaticsub': True,
    'subtitleslangs': ['en', 'en-US'],
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(VIDEO_URL, download=False)

subs = info.get('subtitles') or info.get('automatic_captions') or {}
for lang, tracks in subs.items():
    json3 = next((t['url'] for t in tracks if t.get('ext') == 'json3'), None)
    if json3:
        captions = requests.get(json3, timeout=20).json()
        text = ' '.join(seg['utf8'] for ev in captions['events']
                        for seg in ev.get('segs', []) if 'utf8' in seg)
        print(lang, text[:200])
        break

Ruta B: atajo de youtube-transcript-api. Cuando solo necesitas el texto y las marcas de tiempo, esta biblioteca es una solución de una sola línea:

from youtube_transcript_api import YouTubeTranscriptApi

api = YouTubeTranscriptApi()
fetched = api.fetch('dQw4w9WgXcQ', languages=['en', 'en-US', 'en-GB'])
for snippet in fetched:
    print(f"{snippet.start:7.2f}  {snippet.text}")

Devuelve un FetchedTranscriptiterable de fragmentos con marcas de tiempo, el código de idioma y un is_generated indicador que te indica si los subtítulos se han generado automáticamente. Pasa una lista ordenada de códigos de idioma como alternativa. Si estás descargando transcripciones en un volumen significativo, redirige el tráfico HTTP subyacente a través de un grupo de proxies, ya que el host de timedtext aplica límites de velocidad muy estrictos a las IP de la nube.

Evita los bloqueos: proxies, encabezados, límites de velocidad y reintentos

Todos los métodos anteriores escalan hasta que YouTube empieza a darse cuenta. A partir de unos pocos cientos de solicitudes por minuto desde una misma IP, verás /youtubei/v1/ , redireccionamientos a consent.youtube.como errores HTTP 429. Hay cinco prácticas que mantienen vivo un proceso de web scraping de YouTube en producción.

1. Rotar las IP residenciales para ejecuciones continuadas. Los proxies de centros de datos siguen funcionando para requests , pero se marcan rápidamente como sospechosas /youtubei/v1/. Un conjunto residencial de más de 150 millones de IP en 195 países hace que el tráfico parezca el de navegadores domésticos normales, lo que marca la diferencia entre un rastreador que funciona durante una semana y uno que se bloquea en una hora. La segmentación geográfica también te permite extraer metadatos bloqueados por región sin necesidad de una VPN. (Consulta nuestra guía interna sobre el uso de proxies con el módulo requests para conocer los detalles de configuración).

2. Aleatoriza los encabezados. Un único User-Agent en miles de solicitudes es una huella digital. Alterna el User-Agent y Accept-Language, y establece un Referer (https://www.youtube.com/) para que la llamada parezca impulsada por la página.

3. Limita la velocidad y retrocede ante el 429. Detecta la limitación de velocidad y haz una pausa de forma exponencial:

import time, random, requests

def fetch(url, attempts=5, **kwargs):
    for i in range(attempts):
        r = requests.get(url, timeout=20, **kwargs)
        if r.status_code == 429 or r.status_code >= 500:
            sleep_for = (2 ** i) + random.random()
            time.sleep(sleep_for)
            continue
        r.raise_for_status()
        return r
    raise RuntimeError(f'Gave up after {attempts} attempts')

4. Gestiona la redirección de la cookie de consentimiento. Las solicitudes de la región de la UE a menudo rebotan a consent.youtube.com. La solución más sencilla es enviar una CONSENT=YES+cb cookie en cada llamada, lo que le indica a YouTube que el banner de consentimiento ya se ha descartado.

requests.get(url, cookies={'CONSENT': 'YES+cb'}, headers=HEADERS)

5. Utiliza una API de scraping gestionada para producción. Controlar la capa de proxy y reintentos está bien para un proyecto paralelo. Para cualquier cosa orientada al cliente, nuestra API Scraper gestiona la rotación de proxies, la aleatorización de encabezados, la renderización de JavaScript y la resolución de CAPTCHA detrás de un único punto final, por lo que tu código se centra en analizar la respuesta de YouTube. Solo pagas por las solicitudes exitosas, lo que hace que la previsión de costes sea manejable. Combina las técnicas anteriores con un manual de estrategias anti-bloqueo probado y la tasa de fallos pasará de ser una «lucha diaria» a «revisar el panel de control una vez a la semana».

Convierte los datos extraídos de YouTube en entradas listas para LLM

La razón por la que la mayoría de los equipos combinan metadatos, comentarios y transcripciones es para alimentar un modelo de lenguaje. Los diccionarios planos anteriores son fáciles de convertir en una única carga útil Markdown que un canal de incrustación o un resumidor al estilo Gemini puede ingestar directamente.

def to_markdown(meta: dict, transcript: str, top_comments: list[dict]) -> str:
    parts = [
        f"# {meta['title']}",
        f"**Channel:** {meta['channel']}  ",
        f"**Published:** {meta.get('upload_date')}  ",
        f"**Views:** {meta.get('view_count')}  ",
        '',
        '## Description',
        meta.get('description', '').strip(),
        '',
        '## Transcript',
        transcript.strip(),
        '',
        '## Top comments',
    ]
    for c in top_comments[:25]:
        parts.append(f"- **{c['author']}**: {c['text']}")
    return '\n'.join(parts)

Una vez que se dispone de una carga útil en Markdown por vídeo, dos pequeños ajustes la hacen apta para la producción en RAG:

  • Divide en fragmentos para las ventanas de contexto. Incluso con modelos de contexto largo, envía fragmentos de 2000 a 4000 tokens con un solapamiento de 200 tokens, de modo que la recuperación pueda extraer la parte correcta sin perder el contexto circundante.
  • Incorpora metadatos estructurados junto con el texto. Almacena videoId, channelId, publishedAty el idioma como columnas separadas en su almacén vectorial. Filtrar por estos criterios en el momento de la consulta es más económico y preciso que basarse únicamente en la similitud semántica.

Este patrón es la razón por la que los equipos que ya saben cómo extraer datos de YouTube tienden a integrarlo en el mismo proceso de ingestión que sus podcasts y seminarios web: el esquema de salida coincide, y el mismo fragmentador/incrustador se reutiliza de forma limpia en todas las fuentes.

Límites legales y éticos del scraping de YouTube

Nada de lo que se incluye en esta guía constituye asesoramiento legal; trátala como una lista de verificación para desarrolladores y consulta a un abogado antes de cualquier implementación comercial. Una vez aclarado esto, hay cuatro límites importantes a tener en cuenta al extraer datos de YouTube.

Condiciones de servicio. Las Condiciones de servicio de YouTube restringen el acceso automatizado de formas que cambian periódicamente; revisa directamente las Condiciones de servicio actuales de YouTube en lugar de fiarte de cualquier resumen de terceros. Incumplirlas puede dar lugar al bloqueo de la IP, la suspensión de la cuenta o acciones legales contra el operador.

Derechos de autor. Los archivos de vídeo, las miniaturas y los metadatos originales del creador están protegidos por derechos de autor en la mayoría de las jurisdicciones. Almacenar o redistribuir ese contenido más allá de los casos de uso legítimo, investigación o uso transformativo sin autorización puede constituir una infracción. La creación de enlaces y el uso analítico de metadatos públicos se encuentran en un terreno mucho más seguro.

Legislación sobre privacidad. Los comentarios y los nombres de usuario de los canales suelen considerarse datos personales. El texto del RGPD de la UE establece requisitos de base legal, minimización y conservación; la CCPA de California impone obligaciones paralelas a un conjunto diferente de actores. Si recopila comentarios de usuarios de la UE o de California, documente una base legal, minimice lo que conserva y ofrezca una vía de eliminación.

Protocolo. Respeta robots.txt incluso cuando no sea estrictamente vinculante, limita el acceso de forma agresiva cuando detectes errores 429, identifica tu rastreador en un User-Agent claramente atribuible para las interacciones de primera mano y detente en cuanto veas una objeción por escrito de un creador o de la propia YouTube.

Puntos clave

  • Elige primero el método. La API de datos v3 está bien para extracciones estructuradas de bajo volumen; todo lo demás (comentarios, transcripciones, Shorts, búsqueda profunda) debe realizarse mediante un proceso de scraping.
  • El ytInitialPlayerResponse truco de la expresión regular es la ruta más rápida sin clave API para obtener el título, el recuento de visualizaciones, el canal y la duración, y funciona tanto en vídeos normales como en Shorts.
  • yt-dlp es la herramienta principal por defecto para metadatos de vídeo, comentarios y transcripciones, ya que se auto-limita y viene con gestión de URL firmadas para subtítulos.
  • Los /youtubei/v1/ desbloquean resultados de búsqueda, paginación de vídeos del canal mediante tokens de continuación y hilos de comentarios profundos, pero necesitan un grupo de proxies y una capa de reintentos compatible con el código 429 para funcionar correctamente.
  • Considera la defensa contra bots, el cumplimiento de los Términos de Servicio y la higiene de GDPR/CCPA como requisitos de producción, no como aspectos secundarios.

Preguntas frecuentes

Los metadatos públicos de YouTube suelen poder recopilarse con fines analíticos y de investigación, pero hacerlo puede infringir los Términos de servicio de YouTube, que restringen el acceso automatizado de formas que cambian periódicamente. Los vídeos y las miniaturas siguen estando protegidos por derechos de autor, y los datos personales en los comentarios activan las obligaciones del RGPD o la CCPA. Revisa los Términos de servicio actuales, documenta una base legal y consulta a un abogado antes de cualquier uso comercial.

¿Cómo puedo extraer comentarios de YouTube sin alcanzar el límite de la API de datos de YouTube?

Evita por completo la API de datos. La opción getcomments=True extrae el texto del hilo, los autores, el recuento de «Me gusta» y los ID de los vídeos originales en una sola llamada, sin cuota y sin clave de API. Para hilos más extensos de vídeos virales, replica el /youtubei/v1/next XHR con el commentContinuationToken de la página de visualización y pagina hasta que la respuesta deje de devolver una nueva continuación.

¿Cuál es la forma más fácil de descargar la transcripción de un vídeo de YouTube en Python?

Instala youtube-transcript-api y llama a YouTubeTranscriptApi().fetch(video_id, languages=['en','en-US','en-GB']). Devuelve fragmentos con marca de tiempo, el código de idioma y un is_generated indicador que señala los subtítulos automáticos. Pasa una lista ordenada de idiomas para una alternativa elegante. Para casos extremos de URL firmadas (subtítulos en directo, contenido exclusivo para miembros), cambia a yt-dlp con writesubtitles=True y lee la json3 URL que genere.

¿Por qué mi rastreador de YouTube empieza a devolver páginas vacías o errores 429?

Tres sospechosos habituales. Estás accediendo desde la misma IP con demasiada frecuencia, así que alterna a proxies residenciales y añade un retroceso exponencial ante los 429. Te están redirigiendo a consent.youtube.com, así que configura una CONSENT=YES+cb cookie. O tu clientVersion encabezado está obsoleto en /youtubei/v1/ las llamadas, así que actualízalo desde una página de visualización actual o sw.js_data una vez por ejecución.

¿Con qué frecuencia cambia YouTube su esquema interno /youtubei/v1 y cómo mantengo mi rastreador en funcionamiento?

Las rutas de los puntos finales y los envoltorios de nivel superior se mantienen estables durante meses, pero los nombres de los campos del renderizador en su interior (videoRenderer, reelItemRenderer, rutas de continuación de comentarios) cambian cada pocas semanas. Protégete contra estos cambios analizando jsonpath-ng o jmespath que sean fáciles de actualizar, supervisando la estructura de la respuesta con instantáneas del esquema y escribiendo pruebas de integración que fallen de forma evidente cuando desaparezca un campo crítico.

Resumen y próximos pasos

Si solo recuerdas una cosa de esta guía, que sea la matriz de decisión: saber cómo extraer datos de YouTube empieza por elegir la herramienta adecuada, no por escribir código. La API de datos para llamadas estructuradas de bajo volumen, yt-dlp para la profundidad por vídeo, /youtubei/v1/ para la búsqueda y la paginación, y una API gestionada cuando la producción está en juego.

Antes de lanzar un rastreador de YouTube, realiza tres comprobaciones de producción. En primer lugar, confirma que tu grupo de proxies rota con la frecuencia suficiente para mantener las tasas de solicitudes por IP en un nivel conservador. En segundo lugar, verifica que tu política de reintentos trate los errores 429, los errores 5xx y las redirecciones de consentimiento como modos de fallo distintos con diferentes curvas de retroceso. En tercer lugar, configura una supervisión que avise de los cambios en la estructura de la respuesta, no solo de los fallos HTTP, para que una desviación silenciosa del esquema /youtubei/v1/ no corrompa una semana de datos.

Combina el scraping de canales con el análisis de sentimiento de los comentarios, la fragmentación de transcripciones o los paneles de control de la cadencia de la competencia y tendrás un verdadero canal de inteligencia. Si prefieres saltarte por completo el proxy y la infraestructura de reintentos, nuestro equipo de WebScrapingAPI ofrece una API de scraper que devuelve HTML o JSON limpio desde cualquier superficie de YouTube con gestión antibots integrada, para que puedas mantener el código de análisis y sustituir la capa de obtención con una sola llamada HTTP.

Acerca del autor
Raluca Penciuc, Desarrollador full-stack @ WebScrapingAPI
Raluca PenciucDesarrollador full-stack

Raluca Penciuc es desarrolladora full stack en WebScrapingAPI, donde se dedica a crear rastreadores, mejorar las técnicas de evasión y buscar formas fiables de reducir la detección en los sitios web de destino.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.