Analyzing YouTube Data: Comment Sentiment and Metadata Extraction with Python
Analyzing video metrics and comment threads is a powerful way to leverage Python for data science, market research, or content optimization. By analyzing the public reception of a video, you can measure audience mood and extract key metadata features.
This guide demonstrates how to build a complete YouTube data extraction pipeline using two separate strategies:
- Metadata Extraction: Retrieving views, tags, categories, and upload details using
yt-dlp(no API key required). - Comment Sentiment Analysis: Scoping comment sections to calculate positive or negative audience polarity using the official YouTube Data API v3 and
TextBlob.
Part 1: Extracting Video Metadata (yt-dlp)
To gather structural details about a video (such as view counts, upload dates, tags, or descriptions), use yt-dlp. This tool queries the page layout directly, meaning you do not need to register for a Google developer account or configure credentials.
Installation
pip install yt-dlp
Python Script: Fetching Metadata
This script runs in "skip download" mode to extract text-based metadata fields without downloading the video file:
import yt_dlp
def get_youtube_metadata(url: str):
# Configure options: quiet logging and skip heavy file downloads
ydl_opts = {
'quiet': True,
'skip_download': True,
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
# Map structural details
metadata = {
"Title": info.get('title'),
"Views": info.get('view_count'),
"Likes": info.get('like_count'),
"Description": info.get('description'),
"Author": info.get('uploader'),
"Duration": info.get('duration'), # Duration in seconds
"Upload Date": info.get('upload_date'),
"Tags": info.get('tags'),
"Categories": info.get('categories')
}
return metadata
except Exception as e:
print(f"Error fetching metadata: {e}")
return None
# Execution
video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
data = get_youtube_metadata(video_url)
if data:
print(f"Title: {data['Title']}")
print(f"Views: {data['Views']:,}")
print(f"Uploader: {data['Author']}")
print(f"Tags: {data['Tags']}")
Handling Restricted Content
If you attempt to extract metadata from age-restricted or private videos, yt-dlp may throw errors. To resolve this, export your browser cookies to a text file and add the cookiefile parameter to your configuration options:
ydl_opts = {
'quiet': True,
'skip_download': True,
'cookiefile': 'cookies.txt'
}
Part 2: Comment Sentiment Analysis (YouTube API & TextBlob)
To analyze the overall mood of a comment section, query the official Google APIs to fetch the comment feed, then parse the strings with natural language processing (NLP).
Prerequisites
- Google Cloud Console: Enable the YouTube Data API v3 in your Google Cloud dashboard and generate an API Key.
- Libraries: Install the official Google client and the
TextBloblibrary:
pip install google-api-python-client textblob
Python Script: Sentiment Analyzer
This script fetches the first 100 comments of a video and calculates the average polarity score (ranging from -1 for negative to +1 for positive):
from googleapiclient.discovery import build
from textblob import TextBlob
import re
API_KEY = "YOUR_YOUTUBE_API_KEY_HERE"
VIDEO_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
def get_video_id(url: str):
# Regex to extract the 11-character video ID
pattern = r'(?:v=|\/)([0-9A-Za-z_-]{11}).*'
match = re.search(pattern, url)
return match.group(1) if match else None
def analyze_comments(video_url: str):
video_id = get_video_id(video_url)
if not video_id:
print("Invalid URL")
return
# Initialize the YouTube client
youtube = build('youtube', 'v3', developerKey=API_KEY)
# Fetch top level comments
request = youtube.commentThreads().list(
part="snippet",
videoId=video_id,
maxResults=100,
textFormat="plainText"
)
response = request.execute()
polarities = []
subjectivities = []
for item in response.get('items', []):
comment_text = item['snippet']['topLevelComment']['snippet']['textDisplay']
# Analyze comment sentiment
analysis = TextBlob(comment_text)
polarities.append(analysis.sentiment.polarity)
subjectivities.append(analysis.sentiment.subjectivity)
if not polarities:
print("No comments found.")
return
avg_polarity = sum(polarities) / len(polarities)
avg_subjectivity = sum(subjectivities) / len(subjectivities)
# Determine general consensus
if avg_polarity > 0.1:
sentiment_label = "Positive"
elif avg_polarity < -0.1:
sentiment_label = "Negative"
else:
sentiment_label = "Neutral"
print(f"Video ID: {video_id}")
print(f"Analyzed Comments: {len(polarities)}")
print(f"Average Polarity: {avg_polarity:.2f} ({sentiment_label})")
print(f"Average Subjectivity: {avg_subjectivity:.2f}")
analyze_comments(VIDEO_URL)
Interpreting Polarity and Subjectivity Scores
When parsing text strings using TextBlob, the evaluation models return two distinct metrics:
1. Polarity Score
Measures the emotional valence of the text, ranging from -1.0 (highly negative) to +1.0 (highly positive):
0.5to1.0: Shows enthusiastic words (e.g. amazing, masterpiece, awesome).-0.1to0.1: Indicates neutral, fact-oriented, or informational comments (e.g. video, details, how-to).-1.0to-0.5: Indicates negative expressions (e.g. broken, hate, terrible, waste).
2. Subjectivity Score
Measures the objectivity of the text, ranging from 0.0 (fully objective facts) to 1.0 (fully subjective opinions). Checking this metric helps you filter out transactional spam comments or bot links (which tend to be highly objective) from genuine user comments.
Sources
- [1] Google Cloud Console Docs: YouTube Data API v3 Getting Started
- [2] TextBlob Documentation: TextBlob Sentiment Analysis Reference
- [3] Natural Language Toolkit: NLTK Official Library Site
- [4] GitHub Project page: yt-dlp Core Repository
- [5] Real Python: Video Processing and Scraping in Python
