YouTube Comments Scraper
Pricing
from $1.50 / 1,000 results
YouTube Comments Scraper
Fast YouTube comments scraper. Paste any video URLs and extract every comment plus full reply threads. Author handle, channel id, exact like count, reply count, hearted, pinned, verified, edited flags, published time. Direct InnerTube API reads, no browser. PPE pricing.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Crikit
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Fast, exhaustive YouTube comments scraper. Paste any YouTube video URLs and extract every comment plus the full reply thread under each one. Direct reads of YouTube's InnerTube API, no headless browser. Built in Python with curl_cffi for clean TLS impersonation.
What you get
One record per comment or reply, in flat row format. Top-level comments have replyLevel = 0, replies have replyLevel = 1 and a parentCommentId linking back to the comment they reply to.
Every field is parsed directly from YouTube's structured comment payload, including:
commentId,parentCommentId,replyLeveltext(plain text rendered from YouTube's run-based content)publishedTimeRelative("1 day ago","3 weeks ago (edited)")isEditedlikeCount(exact integer, parsed from YouTube's accessibility label, not the1.1Kcosmetic string)replyCount(exact integer; 0 on reply rows)authorChannelId,authorHandle,authorDisplayName,authorThumbnailUrlauthorIsVerified,authorIsCreator,authorIsArtistisHearted(creator gave this comment the heart icon)isPinned(top-level only; pinned comments only)videoId,videoUrlscrapedAt(ISO-8601 UTC timestamp)
Input
{"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ","https://youtu.be/jNQXAC9IVRw","dQw4w9WgXcQ"],"sortBy": "TOP","maxCommentsPerVideo": 500,"includeReplies": true,"maxRepliesPerComment": 50,"proxyConfiguration": { "useApifyProxy": true }}
| Field | Type | Description |
|---|---|---|
videoUrls | array, required | YouTube watch URLs, Shorts URLs, youtu.be short links, or raw 11-character video IDs. Each video is scraped independently. |
sortBy | enum, default TOP | TOP returns YouTube's ranked order. NEWEST returns reverse-chronological. |
maxCommentsPerVideo | integer, optional | Hard cap on top-level comments per video. Leave empty to scrape the entire comment section. |
includeReplies | boolean, default true | If on, fetch the full reply thread under every top-level comment. |
maxRepliesPerComment | integer, optional | Hard cap on replies per top-level comment. Leave empty for unlimited. |
proxyConfiguration | object | Datacenter proxy is sufficient for steady-state scraping. Use Residential only if you hit throttling at very high volume. |
Output
One JSON object per dataset row. Example (top-level comment):
{"videoId": "dQw4w9WgXcQ","videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ","commentId": "Ugzge340dBgB75hWBm54AaABAg","parentCommentId": null,"replyLevel": 0,"text": "can confirm: he never gave us up","publishedTimeRelative": "1 year ago","isEdited": false,"likeCount": 241,"replyCount": 960,"authorChannelId": "UCBR8-60-B28hp2BmDPdntcQ","authorHandle": "YouTube","authorDisplayName": "@YouTube","authorThumbnailUrl": "https://yt3.ggpht.com/...","authorIsVerified": true,"authorIsCreator": false,"authorIsArtist": false,"isHearted": true,"isPinned": true,"scrapedAt": "2026-05-19T01:16:49Z"}
A reply has the same shape with replyLevel: 1, a populated parentCommentId, and replyCount: 0.
How it works
The actor calls YouTube's InnerTube API directly (POST /youtubei/v1/next) using curl_cffi with Chrome 131 TLS impersonation. For each input video it:
- Fetches the watch-page HTML once to extract the current
INNERTUBE_CLIENT_VERSIONand the comments-section entry continuation token. - Walks comment pages 20-at-a-time until the comment section ends (or
maxCommentsPerVideois hit). - For each top-level comment with replies, fires a parallel reply-thread fetch (10 replies per page; paginates until the reply thread ends or
maxRepliesPerCommentis hit). - Pushes each comment to the dataset as a flat record.
No browser, no captcha challenge, no signed requests. The whole flow runs at roughly 1-2 requests per second per IP and is safe to run unattended for hours.
Pricing
Pay per comment scraped (Pay Per Event). Replies and top-level comments are both billable rows. Failed videos (private, unavailable, comments disabled) emit nothing and cost nothing.
Edge cases handled
- Comments disabled. Detected; the video is skipped and no rows are emitted.
- Private or unavailable videos. Detected; the video is skipped.
- YouTube Shorts. Same comment endpoint as regular videos; works out of the box.
- Bumped client version. Re-extracted from a fresh watch-page HTML on each run, so it always uses the live version YouTube expects.
- Mid-run rate limiting. Exponential backoff on 429 and 5xx; rotates between
chrome131andchrome124TLS profiles on persistent failures.
Example: scrape every comment on a single video
{"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"sortBy": "TOP","includeReplies": true}
Example: TOP 100 comments per video, no replies, multiple videos
{"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ","https://www.youtube.com/watch?v=jNQXAC9IVRw"],"sortBy": "TOP","maxCommentsPerVideo": 100,"includeReplies": false}
Example: NEWEST 50 comments, plain integer video IDs
{"videoUrls": ["dQw4w9WgXcQ", "jNQXAC9IVRw"],"sortBy": "NEWEST","maxCommentsPerVideo": 50,"includeReplies": true,"maxRepliesPerComment": 5}
Notes on data freshness
The comments returned reflect the state of the comment section at scrape time. Re-running an hour later will pick up any new comments posted since (and any comments that were deleted will disappear). The scrapedAt timestamp is your reference for when the snapshot was captured.