YouTube Comments Scraper
Pricing
from $2.00 / 1,000 results
YouTube Comments Scraper
Scrape the comments of one or MANY YouTube videos in a single run. Returns text, author, likes, thread structure (parent/depth) and the source video itself. Top or newest-first order, optional replies. No login, no API quota.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
code craker
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
Apify actor that scrapes the comments of one or many YouTube videos in a single run and exports them as structured data — no login, no cookies, no YouTube API quota.
It reads the entry token from the video's watch page and pages through YouTube's own
InnerTube /youtubei/v1/next API (the same requests the site itself makes). Requests
go over plain HTTP first (fast and cheap); if YouTube blocks that, the actor
automatically escalates to a real Chrome browser for the rest of the run — API
requests then run inside the page as same-origin fetches.
Features
- Batched: pass many video URLs and they are all scraped in ONE actor run
(
maxCommentsapplies per video). Results are pushed after each video, so an abort or timeout keeps everything collected so far. - Any video reference works:
youtube.com/watch?v=...,youtu.be/...short links,/shorts/...links, or a bare 11-character video id. top(YouTube's ranked order) ornewestfirst.- Replies included with full thread structure (
parentCommentId+depth), or top-level comments only (includeReplies: false). Top-level comments are collected first; replies fill the remaining budget. - The source video itself is emitted too (flagged
is_source_post: true) with title, channel, views, exact publish date and total comment count; disable withincludeSourcePost: false. Videos with disabled comments are flagged (commentsDisabled: true) instead of failing. - Automatic block recovery: fresh proxy IP on each retry, plain HTTP → real Chrome escalation, EU consent interstitial bypassed via cookies.
- When a run ends with 0 results, the last page fetched is saved as
DEBUG_HTMLin the run's key-value store.
Input
{"urls": ["https://www.youtube.com/watch?v=XXaUd0fGpOs","https://youtu.be/SSE4M0gcmvE"],"maxComments": 100,"commentsSort": "top","includeReplies": true,"includeSourcePost": true,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "US"}}
startUrls ([{ "url": ... }]) is accepted as an alternative to urls and merged
with it. resultsLimit is accepted as an alias for maxComments.
Output
One dataset item per comment. Every item carries postId / postUrl / inputUrl,
so comments from a multi-video run can always be attributed back to their source
video.
{"id": "Ugw4obgfNOpuN6L96qF4AaABAg","url": "https://www.youtube.com/watch?v=XXaUd0fGpOs&lc=Ugw4obgfNOpuN6L96qF4AaABAg","text": "Full text of the comment...","author": "@some_user","authorChannelId": "UCQLsJdT08EKD_7boRxYusGw","authorProfileUrl": "https://www.youtube.com/channel/UCQLsJdT08EKD_7boRxYusGw","authorAvatar": "https://yt3.ggpht.com/...","isCreator": false,"isVerified": false,"likeCount": 52,"repliesCount": 3,"edited": false,"parentCommentId": null,"depth": 0,"publishedTimeText": "14 hours ago","created_at": "2026-07-08T18:53:19.009Z","postId": "XXaUd0fGpOs","postUrl": "https://www.youtube.com/watch?v=XXaUd0fGpOs","inputUrl": "https://www.youtube.com/watch?v=XXaUd0fGpOs","commentsSort": "top","is_source_post": false}
parentCommentIdisnullfor a top-level comment; otherwise the id of the comment it replies to (YouTube threads are exactly two levels deep). A reply's own id isparentId.replyId.created_atis APPROXIMATE: YouTube only exposes relative publish times for comments ("2 weeks ago"); the raw value is kept inpublishedTimeText.isCreatormarks the video's own channel commenting (YouTube's Creator badge) — the equivalent of Reddit'sisSubmitter/OP.- The source video item has
is_source_post: truewithtitle,description,channelName,viewCount,numCommentsand an EXACTcreated_at(watch pages expose the real publish date).
Integration (scraping-tool)
Batched, like the other comment scrapers in scrapeCommentsForPostsBatched.
Add a branch to scrapingService.scrapeCommentsBatch:
} else if (actor === 'outspoken_strategy/youtube-comments-scraper') {delete input.startUrls;input.urls = urls;input.maxComments = cappedComments(input.maxComments ?? resultsLimit);input.includeSourcePost = input.includeSourcePost ?? false;input.includeReplies = input.includeReplies ?? false; // match FB: top-level onlyinput.proxyConfiguration = input.proxyConfiguration ?? { useApifyProxy: true, apifyProxyGroups: ['RESIDENTIAL'], apifyProxyCountry: 'US' };}
Attribution in _matchCommentToPost (platform youtube): match on item.postUrl,
item.inputUrl or item.postId — a good _postMatchKey is the video id extracted
with /[?&]v=([A-Za-z0-9_-]{11})/ (plus the youtu.be/shorts variants).
Normalization hints: likesCount ← likeCount, repliesCount is already named,
createdTime ← created_at (approximate), parentCommentId is already named, and
author fields are flat (author, authorChannelId, authorProfileUrl).
Local development
npm installecho '{ "urls": ["https://www.youtube.com/watch?v=XXaUd0fGpOs"], "maxComments": 25, "proxyConfiguration": { "useApifyProxy": false } }' > storage/key_value_stores/default/INPUT.jsonnpm start
Deploy with apify push.