Une chaîne YouTube publique est un jeu de données compact qui se cache à la vue de tous. Ouvrez l'onglet Vidéos d'un créateur et vous pouvez voir, pour chaque mise en ligne, le titre, le nombre de vues, la date de publication, la durée et un lien vers la page de visionnage. Agrégées sur une chaîne, ces métadonnées publiques alimentent l'analyse de contenu concurrentielle, la recherche sur les cadences de publication et le suivi des tendances, le tout sans toucher à un seul compte privé.

Ce guide vous montre comment construire un scraper de chaîne YouTube en JavaScript et Node.js. Vous construisez un scraper petit et exécutable qui récupère la page Vidéos d'une chaîne publique via la Crawling API avec le rendu JavaScript, analyse chaque carte vidéo avec cheerio et exporte les résultats en JSON ou CSV. L'ensemble du tutoriel reste limité aux données publiques et non personnelles : les listes de vidéos sur une chaîne que n'importe qui peut ouvrir, jamais les playlists privées, les commentaires ou quoi que ce soit derrière une connexion. La section légale vers la fin n'est pas du remplissage, lisez-la avant de pointer ceci sur un volume réel.

Ce que vous allez construire

Un script Node.js qui prend l'URL Vidéos d'une chaîne YouTube publique, récupère le HTML rendu en JavaScript via la Crawling API, et extrait un enregistrement structuré pour chaque vidéo sur cette page. Nous utilisons l'onglet Vidéos d'une chaîne publique comme exemple fil rouge et extrayons ces champs par vidéo :

  • Title le titre de la vidéo tel qu'il apparaît sur la carte, par exemple « Official Trailer ».
  • Views le texte public du nombre de vues, comme « 56K views ».
  • Upload date la date de publication relative, comme « 6 days ago ».
  • Duration le badge de durée sur la miniature, comme « 2:14 ».
  • Link l'URL absolue vers la page de visionnage individuelle.

Nous lisons aussi un peu de contexte au niveau de la chaîne (le titre et le handle de la chaîne) pour que chaque export se décrive lui-même, puis nous écrivons la liste de vidéos en JSON et CSV.

Pourquoi une simple requête échoue sur YouTube

Si vous demandez l'URL Vidéos d'une chaîne avec un simple client HTTP, vous obtenez un statut 200 et presque aucune des données que vous cherchez. YouTube construit la grille de vidéos dans le navigateur : le HTML initial est un shell fin, et le vrai balisage des cartes est injecté par JavaScript après l'exécution des scripts de la page et le chargement des données de visionnage. Un fetch brut capture la page avant que rien de tout cela ne se produise, donc cheerio trouve une grille vide.

En plus du rendu, YouTube surveille le trafic automatisé. Les IP de datacenter et les schémas de requêtes qui ne ressemblent pas à un vrai navigateur sont rapidement mis en défi ou limités en débit, de sorte que même un navigateur sans interface sur un serveur nu a tendance à se bloquer. Un scraper de chaîne fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la grille, et une IP que la plateforme lit comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur sans interface plus un pool de proxies résidentiels rotatifs, mais les assembler et les maintenir en bonne santé représente l'essentiel du travail. La Crawling API regroupe les deux en un seul appel : vous lui envoyez l'URL avec le rendu JavaScript activé, elle rend la page derrière une IP de confiance, et elle retourne le HTML fini pour que vous l'analysiez.

Why render the page

Crawlbase propose deux types de requêtes. Une requête normale récupère le HTML statique ; une requête JavaScript rend d'abord la page dans un vrai navigateur. YouTube construit la grille de vidéos côté client, donc la requête JavaScript est ce qui vous donne une page peuplée ici. Une requête normale retourne le shell vide, ne laissant rien à analyser à cheerio. Les options ajax_wait et page_wait vous permettent d'attendre que la grille finisse de se charger.

Prérequis

Vous avez besoin de quelques éléments en place avant d'écrire du code. Aucun ne prend longtemps.

Basic JavaScript and Node.js. Vous devez être à l'aise pour écrire et exécuter un script Node et installer des paquets avec npm. Si vous êtes nouveau sur Node, la documentation officielle et n'importe quel cours débutant vous amèneront au niveau que suppose ce tutoriel. Pour un tutoriel plus complet, consultez notre guide sur comment construire un scraper web avec Node.js.

Node.js 16 or later. Confirmez votre version avec node --version. Si vous ne l'avez pas, installez-le depuis le site Node.js ou via un gestionnaire de versions comme nvm.

A Crawlbase account and token. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token de requête JavaScript depuis la page de documentation du compte. Traitez le token comme un mot de passe : il authentifie vos requêtes, donc gardez-le hors du contrôle de version. Les nouveaux comptes incluent un lot de requêtes gratuites, et vous ne payez que pour les réussies, ce qui est largement suffisant pour suivre ce tutoriel.

Configurer le projet

Créez un dossier de projet, initialisez-le et installez les deux bibliothèques dont le scraper a besoin.

bash
node --version

mkdir youtube-channel-scraper && cd youtube-channel-scraper
npm init -y

npm install crawlbase cheerio

Deux dépendances font le travail : crawlbase est le client Node officiel pour la Crawling API, et cheerio analyse le HTML retourné avec une API de style jQuery afin que vous puissiez extraire des champs individuels par sélecteur CSS. Si les sélecteurs sont nouveaux pour vous, le guide sur le crawler de sites JavaScript s'associe bien à ce guide.

Étape 1 : Récupérer la page Vidéos rendue

Commencez par récupérer la page finie. Importez la classe CrawlingAPI, initialisez-la avec votre token, et demandez l'URL Vidéos de la chaîne. Comme la grille se rend côté client, passez ajax_wait et un page_wait pour que les cartes chargées tardivement apparaissent avant que la page ne soit capturée. Vérifier le code de statut avant d'analyser garde les échecs bruyants plutôt que silencieux.

javascript
const { CrawlingAPI } = require('crawlbase');

const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' });

async function crawl(pageUrl) {
  const options = { ajax_wait: 'true', page_wait: 7000 };
  const response = await api.get(pageUrl, options);
  if (response.statusCode === 200) {
    return response.body;
  }
  console.error(`Request failed: ${response.statusCode}`);
  return null;
}

const channelUrl = 'https://www.youtube.com/@Netflix/videos';
crawl(channelUrl).then((html) => {
  console.log(html ? html.slice(0, 500) : 'No HTML returned');
});

Les deux options d'attente comptent pour une cible rendue côté client comme celle-ci. ajax_wait indique à l'API d'attendre que le contenu asynchrone finisse de charger, et page_wait maintient un nombre fixe de millisecondes après le chargement pour que la grille de vidéos chargée tardivement apparaisse avant que la page ne soit capturée. Sept secondes est un bon point de départ pour YouTube ; augmentez si la grille revient vide. Exécutez le script avec node scraper.js et vous devriez voir le vrai balisage de la chaîne, pas un shell allégé. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur.

Crawlbase Crawling API

Cette grille YouTube a besoin d'une page rendue derrière une IP de confiance, en un seul appel. La Crawling API prend votre token, exécute la page dans un vrai navigateur, attend la fenêtre ajax_wait et page_wait que vous venez de définir, effectue une rotation à travers des IP résidentielles côté serveur, et vous remet un HTML fini, vous évitant d'exploiter vous-même une flotte de navigateurs sans interface et un pool de proxies. Pointez-la vers une chaîne publique sur le niveau gratuit d'abord.

Étape 2 : Analyser chaque vidéo avec cheerio

Avec le HTML rendu en main, chargez-le dans cheerio et parcourez les cartes vidéo. L'onglet Vidéos rendu dispose chaque mise en ligne dans un rendu de grille répétitif, donc vous sélectionnez chaque carte, puis lisez le titre, les vues, la date de mise en ligne, la durée et le lien de visionnage à l'intérieur. Lire chaque champ défensivement empêche une valeur manquante de faire planter l'exécution, et l'URL relative sur l'ancre du titre doit être rendue absolue.

javascript
const cheerio = require('cheerio');

function parseChannel(html) {
  const $ = cheerio.load(html);
  const channel = {
    title: $('#inner-header-container .ytd-channel-name .ytd-channel-name:first').text().trim(),
    channelHandle: $('.meta-item #channel-handle').text().trim(),
    videos: [],
  };

  $('#contents ytd-rich-item-renderer').each((_, el) => {
    const card = $(el);
    const title = card.find('#video-title').text().trim();
    if (!title) return;

    const meta = card.find('#metadata-line span');
    const href = card.find('a#video-title-link').attr('href')
      || card.find('a#thumbnail').attr('href');

    channel.videos.push({
      title,
      views: $(meta).eq(0).text().trim() || null,
      uploadDate: $(meta).eq(1).text().trim() || null,
      duration: card.find('#overlays #text').text().trim() || null,
      link: href ? new URL(href, 'https://www.youtube.com').href : null,
    });
  });

  return channel;
}

Quelques détails rendent ceci résilient. La grille de vidéos utilise les cartes ytd-rich-item-renderer de YouTube, et à l'intérieur de chacune #video-title contient le titre tandis que #metadata-line span contient les deux spans de métadonnées : le premier est le nombre de vues, le second est la date de mise en ligne relative. Le badge de durée se trouve dans l'overlay de la miniature sous #overlays #text. Le lien de visionnage est lu depuis l'attribut href de l'ancre avec attr plutôt que depuis son texte, puis passé au constructeur URL afin qu'un chemin relatif /watch?v=... devienne un lien absolu. Chaque champ revient à null quand l'élément est absent.

Selectors drift

Les ids d'éléments et les tags de rendu de YouTube (ytd-rich-item-renderer, #video-title, #metadata-line, et les autres) changent sans préavis, et le balisage diffère entre l'onglet Vidéos, les Shorts et la page d'accueil de la chaîne. Traitez les sélecteurs ci-dessus comme un modèle de départ, pas comme un contrat. Quand un champ revient comme null, inspectez à nouveau la page rendue en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. La maintenance périodique des sélecteurs est normale pour tout scraper en production, pas le signe que quelque chose est cassé.

Étape 3 : Tout assembler

Maintenant, connectez le fetch et le parseur en un seul script exécutable. Récupérez le HTML rendu, passez-le au parseur, et imprimez l'enregistrement structuré de la chaîne.

javascript
const { CrawlingAPI } = require('crawlbase');
const cheerio = require('cheerio');

const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' });

async function crawl(pageUrl) {
  const options = { ajax_wait: 'true', page_wait: 7000 };
  const response = await api.get(pageUrl, options);
  if (response.statusCode === 200) return response.body;
  console.error(`Request failed: ${response.statusCode}`);
  return null;
}

function parseChannel(html) {
  const $ = cheerio.load(html);
  const channel = {
    title: $('#inner-header-container .ytd-channel-name .ytd-channel-name:first').text().trim(),
    channelHandle: $('.meta-item #channel-handle').text().trim(),
    videos: [],
  };
  $('#contents ytd-rich-item-renderer').each((_, el) => {
    const card = $(el);
    const title = card.find('#video-title').text().trim();
    if (!title) return;
    const meta = card.find('#metadata-line span');
    const href = card.find('a#video-title-link').attr('href')
      || card.find('a#thumbnail').attr('href');
    channel.videos.push({
      title,
      views: $(meta).eq(0).text().trim() || null,
      uploadDate: $(meta).eq(1).text().trim() || null,
      duration: card.find('#overlays #text').text().trim() || null,
      link: href ? new URL(href, 'https://www.youtube.com').href : null,
    });
  });
  return channel;
}

async function main() {
  const channelUrl = 'https://www.youtube.com/@Netflix/videos';
  const html = await crawl(channelUrl);
  if (!html) return;
  const channel = parseChannel(html);
  console.log(`${channel.title} (${channel.channelHandle}): ${channel.videos.length} videos`);
  console.log(JSON.stringify(channel.videos.slice(0, 3), null, 2));
}

main();

À quoi ressemble le résultat

Exécutez le script complet avec node scraper.js et vous obtenez un tableau propre d'enregistrements, un par vidéo, prêt à écrire en JSON, CSV ou dans une base de données. Les nombres de vues et les dates de mise en ligne sont les chaînes publiques exactement telles que YouTube les affiche.

json
[
  {
    "title": "Ilary Blasi: The one and only | Official Trailer | Netflix",
    "views": "56K views",
    "uploadDate": "6 days ago",
    "duration": "2:14",
    "link": "https://www.youtube.com/watch?v=pNY3NkGX6e8"
  },
  {
    "title": "Verified Stand-Up | Official Trailer | Netflix",
    "views": "50K views",
    "uploadDate": "11 days ago",
    "duration": "1:58",
    "link": "https://www.youtube.com/watch?v=gMIvGpHd2dk"
  }
]

Exporter vers JSON et CSV

Imprimer dans la console convient pour une vérification, mais vous voulez généralement les données sur disque. Écrire en JSON est une ligne ; un petit writer CSV garde chaque vidéo sur sa propre ligne avec les champs échappés afin que les virgules dans un titre ne cassent pas les colonnes.

javascript
const fs = require('fs');

function saveJson(channel, file) {
  fs.writeFileSync(file, JSON.stringify(channel, null, 2));
}

function saveCsv(videos, file) {
  const headers = ['title', 'views', 'uploadDate', 'duration', 'link'];
  const cell = (v) => `"${(v ?? '').replace(/"/g, '""')}"`;
  const rows = videos.map((v) => headers.map((h) => cell(v[h])).join(','));
  fs.writeFileSync(file, [headers.join(','), ...rows].join('\n'));
}

// in main(), after parseChannel():
saveJson(channel, 'channel.json');
saveCsv(channel.videos, 'channel.csv');

L'assistant cell enveloppe chaque valeur entre guillemets et double tout guillemet intégré, l'échappement CSV standard, afin qu'un titre contenant une virgule ou un guillemet reste dans une seule colonne. JSON conserve l'objet chaîne imbriqué ; CSV aplatit juste les lignes vidéo, ce qui est la forme attendue par la plupart des tableurs et outils BI.

Gérer la liste complète de la chaîne

La page Vidéos rendue vous donne le lot de mises en ligne les plus récentes, pas l'intégralité du catalogue, car YouTube charge paresseusement plus de cartes au fur et à mesure que vous faites défiler. Une seule page rendue est une bonne démonstration et représente souvent tout ce dont vous avez besoin pour une recherche sur l'activité récente. Pour aller plus loin dans une chaîne, vous avez deux options qui conservent le même schéma récupération-puis-analyse.

  • Scroll with the render. Passez un page_wait plus long et utilisez les options de défilement de la Crawling API pour que la page charge plus de lignes avant d'être capturée, puis exécutez le même parseChannel sur la grille plus grande.
  • Walk per-video links. Prenez chaque link de la liste analysée et récupérez cette page de visionnage via la même fonction crawl pour enrichir une ligne avec des détails publics provenant de la page vidéo elle-même, puis écrivez un petit parseur pour cette mise en page.

Quelle que soit votre approche, la structure ne change pas : rendu, puis analyse. Gardez votre volume de requêtes modeste afin de lire une chaîne, pas de la tester sous contrainte.

Rester non bloqué

Même avec le rendu géré, YouTube surveille le trafic ressemblant à un scraper. Quelques habitudes maintiennent une exécution saine, et elles s'appliquent à toute cible difficile et populaire.

  • Pace your requests. Marteler les chaînes dans une boucle serrée est le moyen le plus rapide d'être limité. Espacez les requêtes et variez les chaînes que vous récupérez au lieu de crawler un chemin à pleine vitesse.
  • Lean on rotation. Un pool d'IP résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels afin qu'aucune ne déclenche de limite de débit. La Crawling API gère cela pour vous ; si vous construisez votre propre pile, c'est la partie à bien faire.
  • Read the status codes. Une exécution qui commence à retourner des défis ou des erreurs vous dit que le débit ou le niveau IP actuel n'est plus suffisant. Traitez-le comme un signal pour reculer, pas comme du bruit à ignorer.

Pour le guide de jeu plus large, consultez comment scraper des sites web sans être bloqué. Si vous préférez router votre propre trafic à travers un pool rotatif plutôt que d'utiliser l'API gérée, le Smart AI Proxy vous donne la même rotation d'IP résidentielle comme endpoint proxy direct. Pour une forme différente de données YouTube (vidéos et résultats de recherche plutôt qu'une grille de chaîne), consultez notre guide sur comment scraper des données YouTube.

Est-il légal de scraper YouTube ?

Si le scraping de YouTube est autorisé dépend des Conditions d'utilisation de YouTube, de votre juridiction et de ce que vous faites des données. Les conditions de YouTube restreignent l'accès automatisé au site, donc le scraping peut aller à l'encontre de ces conditions quelle que soit la précaution de votre outillage. Aucun des codes ici ne change cela ; il fait simplement fonctionner la partie technique. Lisez les Conditions d'utilisation de YouTube et son robots.txt, respectez ses attentes de débit, et traitez les deux comme la limite de ce que vous collectez.

Gardez le périmètre étroit. Ne collectez que des données publiques et non personnelles : les titres de vidéos, les nombres de vues, les dates de mise en ligne, les durées et les liens de visionnage que n'importe qui peut voir sur une chaîne publique sans se connecter. Agrégez là où vous pouvez (cadence de publication, distributions de vues, tendances thématiques) plutôt que de construire un profil d'un créateur individuel. Ne touchez rien derrière une connexion, aux vidéos privées ou non répertoriées, aux commentaires, ni aux données personnelles des spectateurs et créateurs. Là où des données personnelles sont impliquées, les lois sur la vie privée comme le RGPD et le CCPA s'appliquent : vous avez besoin d'une base légale pour les traiter et vous devez honorer les demandes de suppression et d'accès. Ne redistribuez pas le contenu vidéo protégé par le droit d'auteur vers lequel vous tirez des liens ; un lien vers une page de visionnage publique ne donne pas de licence pour héberger les médias.

Pour tout ce qui va au-delà de la recherche publique ponctuelle, YouTube propose un chemin officiel et sanctionné : la YouTube Data API. Elle retourne les métadonnées de chaînes et de vidéos dans une forme stable et structurée avec un quota clair et des conditions définies, et c'est le bon outil quand vous avez besoin de volume, de fiabilité ou de droits commerciaux. Ce guide est délibérément limité aux pages de liste de chaînes publiques parce que c'est la ligne qui rend le travail défendable. Il ne couvre pas les vidéos privées, les commentaires, les données des spectateurs, le contenu réservé aux comptes, ni aucune tentative de contourner l'authentification. Si votre projet nécessite plus que des listes publiques, la YouTube Data API ou un accord de données est la bonne voie, pas un scraper plus astucieux.

Récapitulatif

Points clés

  • YouTube rend la grille côté client. Une requête simple retourne un shell vide, vous devez donc rendre la page Vidéos avant de l'analyser.
  • Vous avez besoin du rendu et d'une IP de confiance ensemble. La Crawling API avec une requête JavaScript fait les deux en un appel ; ajax_wait et page_wait contrôlent combien de temps elle attend les cartes.
  • cheerio fait l'extraction. Sélectionnez chaque carte ytd-rich-item-renderer, puis mappez titre, vues, date de mise en ligne, durée et le lien de visionnage aux sélecteurs actuels, et attendez-vous à ce que ces sélecteurs dérivent.
  • Exportez et passez à l'échelle avec prudence. Écrivez en JSON pour la structure et en CSV pour les tableurs, et allez plus loin dans une chaîne avec des rendus plus longs ou des fetches par vidéo plus une régulation sensée.
  • Restez sur les données publiques. Respectez les CGU et le robots.txt de YouTube, préférez la YouTube Data API officielle pour un usage commercial ou à volume, respectez le RGPD et le CCPA quand des données personnelles sont impliquées, et ne touchez jamais aux connexions, vidéos privées ou commentaires.

Foire aux questions

Pourquoi une simple requête renvoie-t-elle une grille vidéo vide depuis YouTube ?

Parce que YouTube construit la grille de vidéos dans le navigateur avec JavaScript. Le HTML initial est un shell fin, et le vrai balisage des cartes n'est injecté qu'après l'exécution des scripts de la page et le chargement des données de visionnage, donc une requête HTTP brute retourne un statut 200 avec la grille vide. Pour obtenir une page peuplée, vous devez d'abord la rendre, ce que gère pour vous la requête JavaScript de la Crawling API.

Ai-je besoin d'une requête normale ou JavaScript pour YouTube ?

Utilisez une requête JavaScript. Une requête normale récupère le HTML statique, qui sur une chaîne YouTube revient comme le shell vide sans cartes. La requête JavaScript rend la page dans un vrai navigateur avant de retourner le HTML, et les options ajax_wait et page_wait donnent à la grille le temps de finir de charger afin que cheerio ait des cartes à analyser.

Mes sélecteurs renvoient null. Qu'est-ce qui a changé ?

Presque certainement le balisage de YouTube. Ses tags de rendu et ses ids d'éléments (ytd-rich-item-renderer, #video-title, #metadata-line, et les autres) changent sans préavis, et ils diffèrent entre l'onglet Vidéos, les Shorts et la page d'accueil de la chaîne, donc des sélecteurs qui fonctionnaient le mois dernier peuvent se casser. Inspectez à nouveau une page rendue en direct dans les outils de développement de votre navigateur et mettez à jour les sélecteurs. La maintenance périodique des sélecteurs est normale pour tout scraper en production.

Comment récupérer toutes les vidéos, pas seulement le dernier lot ?

Le premier rendu retourne les mises en ligne les plus récentes car YouTube charge paresseusement plus de cartes au défilement. Pour remonter plus loin, passez un page_wait plus long avec les options de défilement de la Crawling API afin que plus de lignes chargent avant la capture, puis exécutez le même parseur sur la grille plus grande. Pour les catalogues très anciens, la YouTube Data API officielle pagine les mises en ligne de la chaîne proprement et convient mieux.

Dois-je utiliser l'API YouTube Data ou scraper le site ?

Si vous avez besoin de volume, d'une structure garantie ou de droits de réutilisation commerciale, utilisez la YouTube Data API officielle. Elle est conçue pour cela et vous maintient du bon côté des conditions de YouTube. Le scraping des listes de chaînes publiques avec l'approche de ce guide convient aux recherches plus petites sur les données publiques où aucun accès API n'est en place, tant que vous respectez les CGU, le robots.txt et les limites de débit.

Puis-je scraper les commentaires ou les données d'audience d'une chaîne ?

Non, et ce guide ne le couvre pas. Les commentaires sont du contenu personnel écrit par des utilisateurs, et les données des spectateurs ne sont pas publiques, donc les deux sont en dehors du périmètre public et non personnel de ce guide. Là où des données personnelles sont impliquées, le RGPD et le CCPA s'appliquent et vous avez besoin d'une base légale ainsi que d'un moyen d'honorer les demandes de suppression. Pour un accès sanctionné à ce type de données, la YouTube Data API avec le consentement et les conditions appropriés est la bonne voie.

Commencer à construire

Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.

Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.

En libre-service · Sans appel commercial requis · Volumes de crawl entreprise disponibles