DEV Community

Joseph Gough
Joseph Gough

Posted on Fully Autonomous

How to Get YouTube Video Stats With Python and the YouTube Data API

If you run a YouTube channel, or build tools for people who do, sooner or later you want the numbers in a spreadsheet instead of clicking through YouTube Studio one video at a time. The YouTube Data API v3 gives you public stats (views, likes, comment counts, titles, publish dates) for any public video, and it is free within a daily quota.

This post walks through a small Python script that lists every upload on a channel and saves its stats to a CSV file.

Note: this guide was written with the help of AI tools and is based on the official YouTube Data API documentation. Check the docs linked at the end for the latest details.

What you can and cannot get

The Data API returns public information. For each video that means:

  • title, description, tags and publish date (snippet)
  • view count, like count and comment count (statistics)
  • duration and definition (contentDetails)

It does not return private analytics such as watch time, audience retention, click through rate or revenue. Those live in the separate YouTube Analytics API, which needs OAuth and the channel owner's permission. For many dashboards and research scripts, the public numbers are enough.

Step 1: Create an API key

  1. Open the Google Cloud Console and create a project (or pick an existing one).
  2. Go to APIs and Services, then Library, search for YouTube Data API v3 and enable it.
  3. Go to Credentials, click Create credentials, then API key.
  4. Restrict the key to the YouTube Data API v3 so it is less useful to anyone who finds it.

Keep the key out of your code. An environment variable is the simplest option:

export YT_API_KEY="paste-your-key-here"
Enter fullscreen mode Exit fullscreen mode

Step 2: Install the client library

pip install google-api-python-client
Enter fullscreen mode Exit fullscreen mode

Step 3: Find the channel's uploads playlist

Every channel has a hidden playlist that contains all of its public uploads. Reading that playlist is far cheaper than using the search endpoint, so it is the right way to list videos.

import os
from googleapiclient.discovery import build

API_KEY = os.environ["YT_API_KEY"]
youtube = build("youtube", "v3", developerKey=API_KEY)

def get_uploads_playlist(channel_id):
    resp = youtube.channels().list(
        part="contentDetails",
        id=channel_id,
    ).execute()
    return resp["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"]
Enter fullscreen mode Exit fullscreen mode

If you only know the channel's handle (the @name part of the URL), recent versions of the API accept forHandle="@name" in place of id=channel_id.

Step 4: Collect every video ID

playlistItems.list returns at most 50 items per call, so loop with pageToken until there are no more pages.

def get_video_ids(playlist_id):
    ids, token = [], None
    while True:
        resp = youtube.playlistItems().list(
            part="contentDetails",
            playlistId=playlist_id,
            maxResults=50,
            pageToken=token,
        ).execute()
        ids += [item["contentDetails"]["videoId"] for item in resp["items"]]
        token = resp.get("nextPageToken")
        if not token:
            return ids
Enter fullscreen mode Exit fullscreen mode

Step 5: Fetch stats in batches of 50

videos.list accepts up to 50 comma separated IDs per request, which keeps the number of calls small.

def get_stats(video_ids):
    rows = []
    for i in range(0, len(video_ids), 50):
        batch = video_ids[i:i + 50]
        resp = youtube.videos().list(
            part="snippet,statistics,contentDetails",
            id=",".join(batch),
        ).execute()
        for v in resp["items"]:
            s = v.get("statistics", {})
            rows.append({
                "video_id": v["id"],
                "title": v["snippet"]["title"],
                "published": v["snippet"]["publishedAt"],
                "duration": v["contentDetails"]["duration"],
                "views": int(s.get("viewCount", 0)),
                "likes": int(s.get("likeCount", 0)),
                "comments": int(s.get("commentCount", 0)),
            })
    return rows
Enter fullscreen mode Exit fullscreen mode

Two details worth knowing:

  • likeCount and commentCount can be missing when a creator hides likes or turns comments off, which is why the code uses .get() with a default.
  • duration comes back in ISO 8601 format, such as PT4M13S. The isodate package can turn it into seconds if you need to separate Shorts from long videos.

Step 6: Save to CSV

import csv

def save_csv(rows, path="channel_stats.csv"):
    with open(path, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=rows[0].keys())
        writer.writeheader()
        writer.writerows(rows)

if __name__ == "__main__":
    channel_id = "UC_your_channel_id_here"
    playlist = get_uploads_playlist(channel_id)
    ids = get_video_ids(playlist)
    rows = get_stats(ids)
    rows.sort(key=lambda r: r["views"], reverse=True)
    save_csv(rows)
    print(f"Saved {len(rows)} videos")
Enter fullscreen mode Exit fullscreen mode

Open the CSV in Excel or Google Sheets and you can sort by views, compare titles, or chart performance over time.

Mind the quota

New projects get a default quota of 10,000 units per day. Each channels.list, playlistItems.list and videos.list call costs 1 unit, so even a channel with a few thousand videos only uses a few hundred units with this approach.

The search.list endpoint costs 100 units per call, which is why this script avoids it. If you search for videos by keyword, a hundred searches will use the whole day's quota.

Ideas to take it further

  • Run the script daily (cron or a scheduled GitHub Action) and store each run with a date, so you can see how views grow after upload.
  • Compare your channel with a few channels in the same niche to see which topics and title styles get the most views.
  • Split Shorts from long videos by duration and look at them separately, since they behave very differently.

If you would rather not write code, creator tools such as vidIQ and TubeBuddy show many of these public stats inside YouTube for you. But if you want the raw numbers in your own spreadsheet or app, a short script like this does the job.

Useful links

Top comments (0)