Back to all posts

How to Scrape YouTube Video Comments - The Easy Way

Jonathan Geiger
YouTube APIComment ExtractionYouTube ScrapingSocial Media AnalyticsYouTube Shorts

Need to extract YouTube video comments programmatically? Whether you're building sentiment analysis tools, community management dashboards, or social listening platforms, getting reliable YouTube comment data is essential.

In this guide, we'll show you the easiest way to scrape YouTube video comments (including YouTube Shorts) using the YouTube Comments API - no complex scraping infrastructure required.

What Data Can You Extract?

The YouTube Comments API provides comprehensive comment information:

  • Comment Content - Full comment text with formatting
  • Author Information - Channel name, channel ID, and profile picture
  • Engagement Metrics - Like counts and reply counts
  • Timestamps - Exact comment publication dates
  • Channel Links - Direct links to commenter profiles
  • Flexible Limits - Control how many comments to retrieve
  • YouTube Shorts Support - Works with both regular videos and Shorts

Video Tutorial

Watch this comprehensive tutorial on scraping YouTube video data including comments:

The Easy Way: YouTube Comments API

The simplest and most reliable method is using the YouTube Comments API. Here's why:

No Infrastructure Needed - No need to manage proxies, browsers, or API keys
Always Up-to-Date - API automatically handles YouTube changes
Fast & Reliable - Get comment data in seconds with 99.9% uptime
Simple Integration - Just one API call with a YouTube video URL
Structured Data - Clean JSON response ready for your application
YouTube Shorts Compatible - Works seamlessly with Shorts videos

API Endpoint

https://api.socialkit.dev/youtube/comments

Parameters

ParameterTypeRequiredDescription
urlstringYesYouTube video URL (regular or Shorts)
access_keystringYesYour API access key
limitnumberNoNumber of comments to retrieve (max 100, default 10)
sortBystringNoSort comments by 'top' (most popular) or 'new' (most recent, default)

Example Request

GET https://api.socialkit.dev/youtube/comments?access_key=<your-access-key>&url=https://youtube.com/watch?v=dQw4w9WgXcQ&limit=2&sortBy=top

Example Response

{
  "success": true,
  "data": {
    "url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
    "comments": [
      {
        "author": "@YouTube",
        "text": "can confirm: he never gave us up",
        "likes": 88,
        "date": "",
        "avatar": "https://yt3.ggpht.com/Bg5wS82KGryRmcsn1YbPThtbXoTmj2XJ9_7LmuE2RF6wbKJBkovfRypbSz6UD3gEu_nHiwGZtQ=s88-c-k-c0x00ffffff-no-rj",
        "replyCount": 1,
        "position": 1
      },
      {
        "author": "@IIIII911IIIII",
        "text": "But link sayd free robux",
        "likes": 375,
        "date": "",
        "avatar": "https://yt3.ggpht.com/ixP_4DyuJRryaowxiBKNKv_pvpbEyQHIQrHCZODkNBW-0Lk7eTYo_vL1iB3mL4TFgnV0PNVQiQ=s88-c-k-c0x00ffffff-no-rj",
        "replyCount": 738,
        "position": 2
      }
    ]
  }
}

Code Examples

JavaScript / Node.js

const axios = require('axios');

async function getYouTubeComments(videoUrl, accessKey, limit = 50, sortBy = 'top') {
  try {
    const response = await axios.get('https://api.socialkit.dev/youtube/comments', {
      params: {
        access_key: accessKey,
        url: videoUrl,
        limit: limit,
        sortBy: sortBy
      }
    });
    
    return response.data;
  } catch (error) {
    console.error('Error fetching YouTube comments:', error);
    throw error;
  }
}

// Usage - Works with regular videos
const videoUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
// Also works with YouTube Shorts
const shortsUrl = 'https://www.youtube.com/shorts/abc123def';

const accessKey = 'your-access-key';

// Get top comments (most popular)
getYouTubeComments(videoUrl, accessKey, 50, 'top')
  .then(data => {
    console.log(`Total comments retrieved: ${data.data.comments.length}`);
    
    data.data.comments.forEach(comment => {
      console.log(`\n${comment.author}: ${comment.text}`);
      console.log(`  👍 ${comment.likes} likes | 💬 ${comment.replyCount} replies`);
      console.log(`  Position: #${comment.position}`);
    });
  });

Python

import requests

def get_youtube_comments(video_url, access_key, limit=50, sort_by='top'):
    endpoint = 'https://api.socialkit.dev/youtube/comments'
    
    params = {
        'access_key': access_key,
        'url': video_url,
        'limit': limit,
        'sortBy': sort_by
    }
    
    response = requests.get(endpoint, params=params)
    response.raise_for_status()
    
    return response.json()

# Usage - Works with both regular videos and Shorts
video_url = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
# shorts_url = 'https://www.youtube.com/shorts/abc123def'

access_key = 'your-access-key'

data = get_youtube_comments(video_url, access_key, 50)

print(f"Total comments: {len(data['data']['comments'])}")

for comment in data['data']['comments']:
    print(f"\n{comment['author']}: {comment['text']}")
    print(f"  👍 {comment['likes']:,} likes | 💬 {comment['replyCount']} replies")
    print(f"  Position: #{comment['position']}")

PHP

<?php

function getYouTubeComments($videoUrl, $accessKey, $limit = 50, $sortBy = 'top') {
    $endpoint = 'https://api.socialkit.dev/youtube/comments';
    
    $url = $endpoint . '?' . http_build_query([
        'access_key' => $accessKey,
        'url' => $videoUrl,
        'limit' => $limit,
        'sortBy' => $sortBy
    ]);
    
    $response = file_get_contents($url);
    return json_decode($response, true);
}

// Usage - Supports YouTube videos and Shorts
$videoUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
// $shortsUrl = 'https://www.youtube.com/shorts/abc123def';

$accessKey = 'your-access-key';

$data = getYouTubeComments($videoUrl, $accessKey, 50);

echo "Total comments: " . count($data['data']['comments']) . "\n\n";

foreach ($data['data']['comments'] as $comment) {
    echo "{$comment['author']}: {$comment['text']}\n";
    echo "  👍 " . number_format($comment['likes']) . " likes | 💬 {$comment['replyCount']} replies\n";
    echo "  Position: #{$comment['position']}\n\n";
}

cURL

# Get top comments from regular YouTube video
curl -X GET "https://api.socialkit.dev/youtube/comments?access_key=your-access-key&url=https://youtube.com/watch?v=dQw4w9WgXcQ&limit=50&sortBy=top"

# Get newest comments from YouTube Shorts
curl -X GET "https://api.socialkit.dev/youtube/comments?access_key=your-access-key&url=https://www.youtube.com/shorts/abc123def&limit=50&sortBy=new"

Use Cases

1. Sentiment Analysis Dashboard

Analyze comment sentiment to gauge audience reaction:

async function analyzeCommentSentiment(videoUrl, accessKey) {
  const data = await getYouTubeComments(videoUrl, accessKey, 100);
  const comments = data.data.comments;
  
  // Simple sentiment analysis
  const positiveKeywords = ['love', 'amazing', 'great', 'awesome', 'excellent', 'fantastic'];
  const negativeKeywords = ['hate', 'bad', 'terrible', 'worst', 'awful', 'disappointed'];
  
  let positive = 0, negative = 0, neutral = 0;
  let totalEngagement = 0;
  
  comments.forEach(comment => {
    const text = comment.text.toLowerCase();
    const hasPositive = positiveKeywords.some(word => text.includes(word));
    const hasNegative = negativeKeywords.some(word => text.includes(word));
    
    if (hasPositive && !hasNegative) positive++;
    else if (hasNegative && !hasPositive) negative++;
    else neutral++;
    
    totalEngagement += comment.likes + comment.replyCount;
  });
  
  return {
    total: comments.length,
    positive: positive,
    negative: negative,
    neutral: neutral,
    positiveRate: ((positive / comments.length) * 100).toFixed(2) + '%',
    negativeRate: ((negative / comments.length) * 100).toFixed(2) + '%',
    avgEngagement: (totalEngagement / comments.length).toFixed(2)
  };
}

2. Top Commenters Identifier

Find the most engaged users in your comments:

def find_top_commenters(video_url, access_key, min_threshold=10):
    """Identify most engaged commenters by likes received"""
    
    data = get_youtube_comments(video_url, access_key, 100)
    comments = data['data']['comments']
    
    # Filter and sort by engagement
    engaged_commenters = [
        {
            'author': c['author'],
            'channelUrl': c['channelUrl'],
            'comment': c['text'][:100] + '...' if len(c['text']) > 100 else c['text'],
            'likes': c['likes'],
            'replies': c['replyCount'],
            'engagement_score': c['likes'] + (c['replyCount'] * 2)
        }
        for c in comments if c['likes'] >= min_threshold
    ]
    
    # Sort by engagement score
    engaged_commenters.sort(key=lambda x: x['engagement_score'], reverse=True)
    
    return engaged_commenters[:10]

3. YouTube Shorts vs Regular Video Analysis

Compare engagement between Shorts and regular videos:

async function compareVideoTypes(regularVideoUrl, shortsUrl, accessKey) {
  const [regularData, shortsData] = await Promise.all([
    getYouTubeComments(regularVideoUrl, accessKey, 100),
    getYouTubeComments(shortsUrl, accessKey, 100)
  ]);
  
  const calculateMetrics = (comments) => {
    const totalLikes = comments.reduce((sum, c) => sum + c.likes, 0);
    const totalReplies = comments.reduce((sum, c) => sum + c.replyCount, 0);
    const avgCommentLength = comments.reduce((sum, c) => sum + c.text.length, 0) / comments.length;
    
    return {
      commentCount: comments.length,
      totalLikes,
      totalReplies,
      avgLikes: (totalLikes / comments.length).toFixed(2),
      avgReplies: (totalReplies / comments.length).toFixed(2),
      avgCommentLength: avgCommentLength.toFixed(0)
    };
  };
  
  return {
    regularVideo: calculateMetrics(regularData.data.comments),
    shorts: calculateMetrics(shortsData.data.comments),
    comparison: {
      moreEngagementIn: regularData.data.comments.reduce((sum, c) => sum + c.likes, 0) >
                         shortsData.data.comments.reduce((sum, c) => sum + c.likes, 0) 
                         ? 'Regular Video' : 'YouTube Shorts'
    }
  };
}

4. Community Management Alert System

Monitor multiple videos for comments requiring attention:

def monitor_videos_for_alerts(video_urls, access_key, alert_keywords):
    """Monitor multiple videos for specific keywords or issues"""
    
    alerts = []
    
    for video_url in video_urls:
        try:
            data = get_youtube_comments(video_url, access_key, 50)
            comments = data['data']['comments']
            
            for comment in comments:
                text_lower = comment['text'].lower()
                
                # Check for alert keywords
                for keyword in alert_keywords:
                    if keyword.lower() in text_lower:
                        alerts.append({
                            'video_url': video_url,
                            'author': comment['author'],
                            'channel_url': comment['channelUrl'],
                            'comment': comment['text'],
                            'likes': comment['likes'],
                            'date': comment['date'],
                            'alert_keyword': keyword,
                            'priority': 'high' if comment['likes'] > 100 else 'normal'
                        })
                        break
        except Exception as e:
            print(f"Error processing {video_url}: {e}")
            continue
    
    # Sort by likes (highest priority first)
    alerts.sort(key=lambda x: x['likes'], reverse=True)
    return alerts

# Usage
videos = [
    'https://www.youtube.com/watch?v=video1',
    'https://www.youtube.com/shorts/short1',
    'https://www.youtube.com/watch?v=video2'
]

keywords = ['help', 'issue', 'problem', 'bug', 'not working', 'refund']
alerts = monitor_videos_for_alerts(videos, 'your-key', keywords)

Response Data Explained

Comment Object Fields

  • author - Commenter's channel name/display name (includes @ prefix)
  • text - Full comment text with formatting preserved
  • likes - Number of likes on the comment (integer)
  • date - Comment date (may be empty string for some comments)
  • avatar - URL to the commenter's profile picture
  • replyCount - Number of replies to this comment
  • position - Position/rank of the comment in the list

YouTube Shorts Support

The API works seamlessly with YouTube Shorts - just pass the Shorts URL:

// Regular YouTube video
const regularUrl = 'https://www.youtube.com/watch?v=abc123';

// YouTube Shorts URL
const shortsUrl = 'https://www.youtube.com/shorts/abc123';

// Both work the same way
const regularComments = await getYouTubeComments(regularUrl, accessKey);
const shortsComments = await getYouTubeComments(shortsUrl, accessKey);

Shorts URL Formats Supported

  • https://www.youtube.com/shorts/VIDEO_ID
  • https://youtube.com/shorts/VIDEO_ID
  • https://youtu.be/VIDEO_ID (when it's a Short)
  • https://m.youtube.com/shorts/VIDEO_ID (mobile)

Supported URL Formats

The API accepts various YouTube video URL formats:

  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://www.youtube.com/shorts/VIDEO_ID
  • https://m.youtube.com/watch?v=VIDEO_ID
  • https://youtube.com/watch?v=VIDEO_ID&t=30s (with parameters)

Error Handling

Always implement proper error handling in production:

async function getYouTubeCommentsWithRetry(videoUrl, accessKey, limit = 50, sortBy = 'top', maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await axios.get('https://api.socialkit.dev/youtube/comments', {
        params: { access_key: accessKey, url: videoUrl, limit: limit, sortBy: sortBy },
        timeout: 30000 // 30 second timeout
      });
      
      if (response.data.success) {
        return response.data;
      }
      
      throw new Error('API returned unsuccessful response');
    } catch (error) {
      console.error(`Attempt ${i + 1} failed:`, error.message);
      
      if (i === maxRetries - 1) {
        throw error;
      }
      
      // Exponential backoff
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}

Pricing

The YouTube Comments API is included in all SocialKit plans:

  • Free: 20 credits (20 comment extractions)
  • Basic: $13/month (2,000 credits)
  • Pro: $27/month (10,000 credits)
  • Ultimate: $79/month (50,000 credits)

Each API request costs 1 credit. View full pricing →

Alternative: Build Your Own Scraper

Want to build your own YouTube comment scraper? It's possible but has challenges:

Challenges

  1. YouTube Data API Quotas - Google's official API has strict daily quotas
  2. Complex Authentication - OAuth 2.0 setup required for official API
  3. Dynamic Loading - Comments load dynamically with infinite scroll
  4. Rate Limiting - YouTube aggressively rate limits scraping attempts
  5. Changing Structure - HTML structure changes frequently
  6. Missing Data - Some comment fields aren't exposed in HTML

Why Use an API Instead?

  • No Quotas - Unlike Google's YouTube Data API, no daily quota limits
  • Simpler Auth - Just an API key, no OAuth complexity
  • Always Works - Automatically handles YouTube changes and updates
  • Better Data - Access to all comment fields in structured format
  • Scale Easily - Process thousands of videos without quota concerns
  • Time Savings - Focus on your application, not API complexity

Complete YouTube Data Toolkit

Beyond comments, you might need other YouTube data:

YouTube APIs:

Free YouTube Tools:

Frequently Asked Questions

How many comments can I retrieve per request?

You can retrieve up to 100 comments per request using the limit parameter. For videos with thousands of comments, make multiple requests.

Are nested replies included?

The API returns top-level comments with reply counts. To get nested replies, you would need to use YouTube's official API or make additional requests.

How fresh is the comment data?

Comments are retrieved in real-time from YouTube, so you always get the latest data including new comments posted seconds ago.

Does it work with live stream comments?

The API is designed for regular video and Shorts comments. Live stream comments require different handling.

Can I get comments from private or unlisted videos?

No, only comments from publicly accessible videos can be retrieved.

What about comments disabled videos?

If comments are disabled, the API will return an empty comments array.

Get Started

Ready to start extracting YouTube comments? Sign up for free and get 20 credits to test the API.

For complete API documentation, visit the YouTube Comments API docs.