YouTube Video Details & Comments Scraper
Pricing
Pay per usage
YouTube Video Details & Comments Scraper
YouTube Video Details Scraper extracts structured data from YouTube videos, including titles, descriptions, tags, views, likes, upload dates, channels, and more. Ideal for research, trend analysis, SEO optimization, and automated video data collection
Pricing
Pay per usage
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
5
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
YouTube Video Details & Comments Scraper
Extract YouTube video metadata and the full comment section in a single run — title, description, views, likes, tags, transcript and channel data, plus top-level comments and their threaded replies, exported to JSON, CSV or Excel.
Comments are on by default here, capped per-thread rather than as one flat slice: commentsPerVideo=20 with maxRepliesPerComment=3 genuinely returns up to 20 threads with up to 3 replies each, so one viral thread can't swallow the whole reply budget. comment_count always stays YouTube's real total — a separate commentsFetched reports exactly what this run pulled, so the two numbers never get silently conflated.
What is YouTube Video Details & Comments Scraper?
It's an Apify actor that pulls complete video metadata (title, description, views, likes, tags, thumbnails, transcript, channel profile) and the comment section — top-level comments and their threaded replies — for every video URL you give it. Comments are charged separately from video rows (video_result vs comment_result), and you can filter which comment rows actually get written (by keyword, minimum likes, or creator-only) without changing the per-video metrics like replyRate or creatorResponseRate, which always describe everything actually fetched, not the filtered subset. YouTube blocks unauthenticated comment/detail requests on datacenter IPs in most measured cases — this actor defaults to a residential proxy and reports which proxy tier actually worked in proxyTierUsed.
What data can I extract with YouTube Video Details & Comments Scraper?
Video rows (type: "video", charged as video_result):
| Field | Description |
|---|---|
title / description / video_id / published_date / duration_seconds | Core video metadata. |
views / likes / engagement_rate | Engagement metrics. |
comment_count / totalCommentCount | YouTube's real total comment count, snapshotted before any fetch limit is applied. |
commentsFetched / parentCommentsFetched / repliesFetched / commentsEmitted | What this run actually pulled vs. what survived your filters. |
creatorReplyCount / replyRate / creatorResponseRate / topCommentLikes / pinnedCommentText | Derived comment-section signals, always computed from everything fetched (unaffected by output filters). |
channel | Object: id, name, handle, url, subscriberCount, logo, badges. |
transcript / transcriptMessage | Timed caption cues, or a status message explaining why none were available. |
tags / hashtags / thumbnails / category / language / live_status | Additional metadata. |
proxyTierUsed | Which proxy tier actually succeeded for this video. |
Comment rows (type: "comment" or "reply", charged as comment_result): commentId, parentId, rootCommentId, text, author, authorId, likeCount, publishedAt, isCreatorComment, isPinned, isHearted, threadRepliesFetched, hasCreatorReply.
Why not build this yourself?
Comment and detail requests get walled with "Sign in to confirm you're not a bot" on datacenter IPs in most measured cases — an 8-video batch test succeeded 1/8 on datacenter proxies and 7/8 on residential, which is why residential is the default here rather than an afterthought, with automatic escalation and retry (up to 3 attempts) when a request gets walled. It also fixes a real accuracy bug found in comment-collecting scrapers built on yt-dlp: requesting comments causes yt-dlp's own post-extractor to silently overwrite comment_count with the fetched count instead of YouTube's real total. This actor snapshots the true total before that happens, so comment_count is never quietly wrong just because you asked for comments.
One useful design choice worth knowing: comment filters (commentKeywords, minCommentLikes, onlyCreatorReplies) only control which comment rows get written — they never change the per-video metrics like creatorResponseRate, which always reflect everything that was actually fetched from YouTube, so a heavily-filtered output doesn't quietly understate the real conversation.
How to use data extracted from YouTube Video Details & Comments Scraper?
- Community managers — pull every comment a creator hasn't replied to yet, sorted and filtered, to prioritize responses.
- Market researchers — analyze full comment sections for product feedback, filtered with
commentKeywordsfor specific complaints or requests. - Content strategists — combine video metadata, transcript and top comments to understand what resonated in a competitor's video.
- Moderation/sentiment teams — use
excludeCommentKeywordsto strip spam/giveaway bait before running sentiment analysis on the remaining comments.
🔼 Input sample
| Parameter | Required | Type | Description | Example |
|---|---|---|---|---|
startUrls | Yes | array | Video URLs or bare 11-character IDs. Playlist/channel/search URLs are rejected with a machine-readable reason rather than a malformed row. | ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"] |
maxItems | No | integer | Stop after this many videos. Comment rows aren't counted against it. 0 = process every URL. Default 0. | 0 |
commentsPerVideo | No | integer | Top-level comment threads per video (0-500). 0 skips comments entirely. Base key maxComments also accepted. Default 20. | 20 |
includeReplies | No | boolean | Toggle the reply tree. When off, maxRepliesPerComment is forced to 0. Default true. | true |
maxRepliesPerComment | No | integer | Cap replies collected per thread, not a slice of a flat list (0-100). Default 3. | 3 |
sortCommentsBy | No | string | top (YouTube-ranked) or new (most recent). Base key sortOrder also accepted. Default "top". | "top" |
commentsDataset | No | string | default (main dataset), separate (child dataset <runId>-comments), or both. Default "default". | "default" |
onlyCreatorReplies | No | boolean | Keep only comments/replies by the channel owner. With keepThreadContext on, the original comment they answered is kept too. Default false. | false |
commentKeywords | No | array | Keep a comment only if it contains at least one of these words (case-insensitive). | ["tutorial"] |
excludeCommentKeywords | No | array | Drop comments containing any of these words, applied before the must-contain list. | ["giveaway"] |
minCommentLikes | No | integer | Drop comments below this like count. Default 0. | 10 |
keepThreadContext | No | boolean | Re-attach a filtered-out parent when its reply survives filtering. Default true. | true |
includeTranscript | No | boolean | Download the caption track as timed cues. Default true. | true |
includeChannelProfile | No | boolean | Fetch the channel About page to resolve the avatar URL (one extra request per video). Default true. | true |
proxyConfiguration | No | object | Common pitfall: default RESIDENTIAL is intentional — measured 1/8 success on datacenter vs. 7/8 on residential. Auto-escalates on a block, up to 3 attempts. | {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]} |
{"startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"commentsPerVideo": 20,"maxRepliesPerComment": 3,"sortCommentsBy": "top"}
🔽 Output sample
{"type": "video","title": "Example Video Title","video_id": "dQw4w9WgXcQ","views": 1500000,"likes": 84000,"comment_count": 12400,"commentsFetched": 80,"parentCommentsFetched": 20,"repliesFetched": 60,"creatorResponseRate": 0.15,"topCommentLikes": 4200,"channel": { "name": "Example Channel", "handle": "@examplechannel", "subscriberCount": "1.2M subscribers" },"proxyTierUsed": "residential","success": true}
▶️ Want to try other scrapers?
| Actor | What it does |
|---|---|
| youtube-search-scraper-channel-contact-links | Search YouTube and pull channel contact links. |
| youtube-community-posts-scraper-keyword-date-monitoring | Monitor a channel's Community tab. |
| youtube-playlist-scraper-with-creator-contact-links | Scrape playlists with creator contact links. |
How to extract YouTube video details and comments programmatically
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("SimpleAPI/youtube-video-details-comments-scraper").call(run_input={"startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"commentsPerVideo": 20,"maxRepliesPerComment": 3,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():if item.get("type") == "video":print(item["title"], item["views"], item["commentsFetched"])
Every run's dataset can also be exported straight to JSON, CSV, Excel or an API endpoint from the Apify Console — no code needed for a one-off pull.
Is it legal to scrape YouTube video details and comments?
Scraping publicly accessible data — including public video metadata and comments — is generally lawful in the US under the precedent set in hiQ Labs v. LinkedIn, which held that scraping data not gated behind a login does not violate the Computer Fraud and Abuse Act. This actor reads only public video pages and comment sections, with no login required. If you extract comment data tied to identifiable individuals, GDPR (EU) and CCPA (California) still govern what you do with it, so review your own use case.
❓ FAQ
Why is comment_count different from commentsFetched?
comment_count (and totalCommentCount) is YouTube's real total for the video, snapshotted before any fetch limit is applied. commentsFetched is how many comment rows this specific run actually collected, bounded by commentsPerVideo and maxRepliesPerComment. They're deliberately kept separate so you always know the true scale vs. what you sampled.
Why does this actor default to a residential proxy?
Measured directly: an 8-video batch succeeded 1/8 on a datacenter proxy (hitting YouTube's bot-check wall) and 7/8 on residential. The default reflects what was actually measured to work, and proxyTierUsed reports which tier succeeded for each video.
Do comment filters change the reported response-rate metrics?
No. creatorResponseRate, replyRate, creatorReplyCount and topCommentLikes are always computed from everything actually fetched from YouTube — filters (commentKeywords, minCommentLikes, onlyCreatorReplies) only control which comment rows get written to output.
What does maxRepliesPerComment actually cap?
Replies per individual thread, not a slice of a flattened reply list — maxRepliesPerComment: 3 with commentsPerVideo: 20 means up to 20 threads each capped at 3 replies, not 3 replies total across all threads.
Why did a video fail with success: false?
Failed video rows carry an error field and are never charged — check commentsStatus and the log for the failure reason (extraction error, bot-wall exhaustion after 3 proxy attempts, or a playlist/channel URL that was rejected as not a single video).
Can I get comments in a separate dataset from video metadata?
Yes — set commentsDataset to "separate" for a child dataset named <runId>-comments, or "both" to write to both the main and child datasets.
How is this different from other YouTube video/comment scrapers on Apify? As observed on the Apify Store on 2026-07-26, most YouTube video-detail scrapers either omit comments entirely or fetch a flat comment list without per-thread reply caps, and several silently overwrite the true comment-count total when comments are requested. This actor keeps comments on by default with per-thread caps and preserves the real total independently.
Conclusion
YouTube Video Details & Comments Scraper turns a video URL into complete metadata plus a genuinely threaded, per-thread-capped comment section — with the real comment total always preserved, no matter how you filter the output.