Python · YouTube

Suivre les statistiques de vidéos YouTube avec Python

YouTube affiche le nombre de vues actuel d'une vidéo, mais pas comment elle y est arrivée. Pour savoir à quelle vitesse une vidéo progresse – la vôtre, celle d'un concurrent ou une campagne que vous avez financée –, il faut noter les chiffres régulièrement. Ce guide construit un petit script qui s'en charge pour vous.

Une fois par jour, il demande à everydata.io les vues, likes et commentaires actuels de chaque vidéo de votre liste, ajoute une ligne à un fichier CSV et affiche le nombre de vues gagnées par chaque vidéo depuis la dernière exécution. En option, il récupère aussi les dernières vidéos d'une chaîne, pour suivre les nouvelles vidéos dès leur premier jour.

Mis à jour le · par everydata.io

Ce que vous aurez à la fin

  • Un fichier CSV avec une ligne par vidéo et par jour : vues, likes, commentaires.
  • La progression des vues depuis la vérification précédente, affichée à chaque exécution.
  • Le suivi automatique des nouvelles vidéos d'une chaîne.

Ce dont vous avez besoin

  • Python 3.10 ou plus récent et pip install requests.
  • Une clé API everydata.io gratuite – créez-la ici – dans la variable d'environnement EVERYDATA_API_KEY.
  • Les vidéos à suivre : l'ID qui suit v= dans le lien, ou le lien complet.

01Voyez ce que l'API renvoie pour une vidéo

L'endpoint de détails vidéo prend un ID ou un lien de vidéo dans id et renvoie les chiffres publics de la page de la vidéo. Exemple documenté abrégé :

Exemple de réponse · GET /ytb/youtube-video-details
{
  "responseStatus": "PAGE_FOUND",
  "responseMessage": "Page successfully found!",
  "videoId": "kJQP7kiw5Fk",
  "title": "Luis Fonsi - Despacito ft. Daddy Yankee",
  "channelName": "LuisFonsiVEVO",
  "viewCount": 9125159593,
  "likeCount": 56673581,
  "likeCountText": "56M",
  "commentCount": 4300000,
  "publishedAt": "2017-01-12T21:00:02-08:00",
  "duration": 282
}

viewCount, likeCount et commentCount sont de simples nombres, prêts à être stockés et comparés. likeCountText est le libellé arrondi que YouTube affiche sur la page.

02Enregistrez les chiffres à chaque exécution

Le script lit dans le fichier CSV le dernier nombre de vues de chaque vidéo, récupère les chiffres actuels, ajoute une nouvelle ligne et affiche la différence.

monitor.py
"""Record views, likes and comments of YouTube videos and print the growth since the last check."""
import csv
import os
import re
import time
from datetime import datetime, timezone
from pathlib import Path

import requests

API = "https://api.everydata.io"
KEY = os.environ["EVERYDATA_API_KEY"]
CSV_FILE = Path("video_stats.csv")
VIDEOS = ["kJQP7kiw5Fk"]  # video IDs or full YouTube links


def api_get(path: str, params: dict) -> dict:
    """GET an everydata.io endpoint. Waits when rate limited (429) and retries a failed page load (5xx) once."""
    retried = False
    for _ in range(4):
        resp = requests.get(f"{API}{path}", params=params, headers={"x-api-key": KEY}, timeout=60)
        if resp.status_code == 429:
            # Too many requests at once. The answer says how long to wait: "... Try again in 12 seconds."
            wait = re.search(r"in (\d+) seconds", resp.text)
            time.sleep(int(wait.group(1)) + 1 if wait else 60)
            continue
        if resp.status_code >= 500 and not retried:
            retried = True  # 5xx answers are not counted against your quota
            time.sleep(10)
            continue
        resp.raise_for_status()  # 4xx (wrong key, quota used up, bad parameter) or a second 5xx
        return resp.json()
    raise RuntimeError("still rate limited after several waits – try again later")


def video_details(video: str) -> dict:
    return api_get("/ytb/youtube-video-details", {"id": video})


def last_views() -> dict[str, int]:
    """Most recent view count per video from earlier runs."""
    if not CSV_FILE.exists():
        return {}
    with CSV_FILE.open(newline="") as f:
        return {r["video_id"]: int(r["views"]) for r in csv.DictReader(f) if r["views"]}


def main() -> None:
    before = last_views()
    now = datetime.now(timezone.utc).isoformat(timespec="seconds")
    new_file = not CSV_FILE.exists()

    with CSV_FILE.open("a", newline="") as f:
        writer = csv.writer(f)
        if new_file:
            writer.writerow(["checked_at", "video_id", "title", "views", "likes", "comments"])
        for video in VIDEOS:
            try:
                v = video_details(video)
            except (requests.RequestException, RuntimeError) as exc:
                print(f"{video}: could not check this time ({exc}) – the next run tries again")
                continue  # one failed video does not stop the others
            video_id = v.get("videoId") or video
            views = v.get("viewCount")
            writer.writerow([now, video_id, v.get("title"), views or "",
                             v.get("likeCount") or "", v.get("commentCount") or ""])
            if views is not None and video_id in before:
                print(f"{v.get('title')}: +{views - before[video_id]:,} views since the last check")


if __name__ == "__main__":
    main()

Lancez-le avec python3 monitor.py. À partir de la deuxième exécution, vous voyez des lignes comme « +12,345 views since the last check ». api_get patiente puis continue lorsque vous envoyez trop de requêtes à la fois (429) et réessaie une fois un chargement de page échoué (5xx) ; une vidéo qui échoue encore est signalée et reprise à l'exécution suivante.

03Récupérez les nouvelles vidéos d'une chaîne

Plutôt que d'ajouter chaque nouvelle vidéo à la main, demandez les dernières vidéos d'une chaîne et ajoutez-les à la liste. L'endpoint des vidéos de chaîne accepte un ID de chaîne ou un lien de chaîne.

monitor.py (à ajouter sous video_details)
def latest_uploads(channel: str) -> list[str]:
    """IDs of the newest regular videos of a channel (channel ID or URL such as https://www.youtube.com/@WWE)."""
    data = api_get("/ytb/youtube-channel-videos", {"id": channel, "filter": "videos_latest"})
    return [item["videoId"] for item in data.get("items", []) if item.get("type") == "video"]


# In main(): watch the five newest uploads of a channel as well as your fixed list
# for video in VIDEOS + latest_uploads("https://www.youtube.com/@WWE")[:5]:
Exemple de réponse · GET /ytb/youtube-channel-videos
{
  "responseStatus": "PAGE_FOUND",
  "responseMessage": "Page successfully found!",
  "channelId": "UCJ5v_MCY6GNUBTO8-D3XoAg",
  "filter": "videos_latest",
  "items": [
    {
      "type": "video",
      "videoId": "b7kl_pcHa0A",
      "title": "Blake Monroe vows to get payback against Giulia: SmackDown exclusive, Sept. 18, 2026",
      "viewCount": 6800,
      "publishedTimeText": "47 minutes ago"
    }
  ]
}

04Exécutez-le une fois par jour

Planifiez le script avec cron (Mac, Linux), le Planificateur de tâches Windows ou une tâche CI planifiée :

crontab
0 6 * * * cd /home/you/yt-monitor && EVERYDATA_API_KEY=ds_your_key /usr/bin/python3 monitor.py >> monitor.log 2>&1

Chaque consultation de vidéo et chaque consultation de chaîne correspond à une requête. Par exemple, trois vidéos vérifiées une fois par jour représentent environ 90 requêtes par mois, dans les limites de l'offre gratuite de 100. Pour des chiffres quotidiens sur de nombreuses vidéos, consultez les tarifs.

Ouvrez video_stats.csv dans un tableur et tracez les vues en fonction de checked_at pour voir la courbe de progression.

Endpoints utilisés dans ce guide

GET/ytb/youtube-video-details

Video Details · API YouTube

GET/ytb/youtube-channel-videos

Channel Videos · API YouTube

Tous les paramètres dans la référence de l’API

Essayez avec vos propres données

L’offre gratuite comprend 100 requêtes par mois, utilisables sur toutes les plateformes – de quoi suivre ce guide de bout en bout.