YouTube Comments Scraper - Comments, Replies, Likes & Authors
Pricing
from $1.46 / 1,000 comment returneds
YouTube Comments Scraper - Comments, Replies, Likes & Authors
For sentiment analysis, community management, creator research and AI training sets: comments and replies from any public video with text, author, channel, likes, replies and age. YouTube rounds like counts before sending them - 42 of 68 measured on 2026-09-08 - so every row says if it is exact.
Pricing
from $1.46 / 1,000 comment returneds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
YouTube Comments Scraper - comments, replies and likes
For sentiment and audience research, creator and competitor analysis, moderation review, and feeding real audience language to an LLM: comments and replies from any public YouTube video — the text, the author and their channel, the like count, the reply count, and how long ago it was posted.
The part that makes this one different is uncomfortable to say out loud: YouTube rounds like counts before it sends them, and it never sends a real date. 312K is not 312,000 — it is somewhere between 311,500 and 312,499, and YouTube will not say which. A scraper that writes "likeCount": 312000 and stops there has handed you a number that looks exact and is not. This one hands you likeCountText: "312K", likeCount: 312000 and likeCountIsExact: false, so a spreadsheet full of them can be sorted honestly.
How often it bites, counted: in the four pages of comments in test/fixtures/ (8 September 2026), of 80 comments 68 carry a like number and 42 of those 68 (62%) are rounded. Small ones (538, 97, 409) come through exact; the other 12 carry no number at all — YouTube writes those as 0 likes in its accessibility text, and this Actor returns 0 marked exact rather than pretending the value is unknown. It depends on the video, which is exactly why the flag is per row rather than a sentence in a README: measured live the same day, a music video's top comments were around 70% rounded while a small business channel's were near zero.
Comments turned off is reported as comments turned off. Measured on 8 September 2026 on six children's videos, all six of which had comments disabled — that comes back as its own row with the reason, not as a video with no comments. And paging really pages: on a video whose header claims 2,457,385 comments, 25 requests returned 500 comments with no duplicates and a continuation to carry on from.
No API key, no login, and no proxy by default — measured 8 September 2026, a plain connection returned HTTP 200. Export as JSON, CSV or Excel.
What every row carries
- The comment:
commentId,text,textLength, andcommentUrl- a link that opens that exact comment on YouTube - The author:
authorName,authorChannelId,authorChannelUrl,authorIsVerified,authorIsArtist, andauthorIsChannelOwner(the video's own channel replying) - The numbers:
likeCountText/likeCount/likeCountIsExact,replyCountText/replyCount - The time:
publishedTimeText("5 days ago") exactly as YouTube shows it,publishedApproxDaysAgo(5), andisEditedsplit out of the text instead of glued to it - The status flags:
isPinnedwithpinnedText,hasCreatorHeart,isReply,replyLevel,parentCommentId - The video:
videoId,videoUrl,videoTitle, andvideoCommentCount- the total YouTube's own header claims, so you can always see how much of the comment section you actually got - Where it came from:
sortedBy,page,rank,scrapedAt
The five things this Actor refuses to fake
1. A rounded number is never presented as exact. Every like count carries likeCountIsExact.
The minLikes filter says in its own description that it compares against the rounded value.
2. The creator's heart is read from the right place. YouTube attaches
heartActiveTooltip: "❤ by @channel" to every single comment - 90 of 90 in the fixtures. Read that
and you mark the whole comment section as hearted. The real state lives in a separate entity
(engagementToolbarStateEntityPayload.heartState) that has to be matched by key. In those same 90
comments, exactly 2 were actually hearted.
3. "Comments are turned off" is never returned as "0 comments". A video with comments disabled serves
a comment section with no comment list in it and a message saying so, and you get a free row carrying
YouTube's own wording. Measured live on
8 September 2026 on six children's videos, all six of which had comments off; one of those responses is
kept in test/fixtures/watch-comments-off.json. Retrying such a video will never produce rows, and this Actor says so
instead of letting you think the audience was silent.
4. No invented dates. YouTube gives comments relative text only. You get the text and an
approximate number of days, named publishedApproxDaysAgo because that is what it is.
5. Coverage is stated, not implied. YouTube serves comments about 20 at a time and stops when it feels like it. Measured live on 8 September 2026 (this one is not in the fixtures): on a video whose header claims 2.4 million comments, 25 requests returned 500 comments with no duplicates and a continuation token still pending. When the rows you get are fewer than the video claims, a free row says so and why the run stopped.
Pinned comments sit first in every order
A pinned comment stays at the top whether you sort by top or by newest, so "the first row of a
newest-first run" is not the newest comment. In test/fixtures/comments-newest.json you can count it: row 1 is a pinned comment from a year ago, and
row 2 was posted 4 minutes before that response was captured. Every row carries isPinned, so you can
drop it or keep it deliberately.
Example output (one row, shortened)
{"videoId": "dQw4w9WgXcQ","videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)","videoCommentCount": 2457385,"commentId": "Ugzge340dBgB75hWBm54AaABAg","commentUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=Ugzge340dBgB75hWBm54AaABAg","text": "can confirm: he never gave us up","authorName": "@YouTube","authorChannelId": "UCBR8-60-B28hp2BmDPdntcQ","authorChannelUrl": "https://www.youtube.com/@YouTube","authorIsVerified": true,"authorIsChannelOwner": false,"likeCountText": "312K","likeCount": 312000,"likeCountIsExact": false,"replyCount": 963,"publishedTimeText": "1 year ago","publishedApproxDaysAgo": 365.3,"isEdited": false,"isPinned": true,"pinnedText": "Pinned by @RickAstleyYT","hasCreatorHeart": true,"isReply": false,"replyLevel": 0,"parentCommentId": null,"sortedBy": "top","page": 1,"rank": 1}
Input
videoUrls- watch URLs,youtu.belinks, Shorts links or plain 11-character video IDs. Anything that is not a YouTube video comes back as a free row rather than being silently dropped.maxCommentsPerVideo- top-level comments per video (default 100).maxRecords- the most rows this run may return and charge for. When the cap bites, rows are taken evenly from every video, so no video disappears completely.sortBy-top(YouTube's default) ornewest.includeRepliesandmaxRepliesPerComment- replies come back as their own rows withparentCommentIdandreplyLevel: 1.keywords,keywordMatch,excludeKeywords- matched against the comment text and author name. YouTube has no server-side comment search, so the filter applies to the comments this run read.minLikes- compares against the rounded like count (see above).onlyVerifiedAuthors,postedWithinDays- comments whose time text cannot be read are kept, not thrown away.monitoringMode,resetMonitoringState- remembers the comment ids already returned to you and returns only new ones. Run it on a schedule to watch a video and pay only for what is new.maxRequests- hard ceiling on requests to YouTube, counting video pages, comment pages and reply pages. It protects you from a runaway run on a video with millions of comments.useProxy- off by default. Measured 8 September 2026: a plain connection returned HTTP 200.
Rows you are never charged for
Every row that is not a comment carries a reason and the words This row is not charged:
status | when |
|---|---|
comments-disabled | YouTube refuses to serve a comment section for this video |
invalid-input | something you passed is not a YouTube video URL or video ID |
no-new-since-last-run | monitoring mode: everything read had already been returned to you |
sort-unavailable | YouTube did not offer the comment order you asked for on that video |
video-unavailable | the ID is wrong, or the video is private, deleted or blocked here |
no-results | the comment section loaded and was empty |
partial-coverage | you got fewer comments than the video claims, and why the run stopped |
unreadable | the answer could not be read - the video page is retried 3 times first |
bot-check | YouTube answered with a bot check instead of comments |
no-match | comments were read but none matched your filters |
request-limit-reached | the run stopped at your maxRequests |
maximum-reached | rows were left out by your maxRecords |
budget-reached | the run hit the maximum total charge set for it |
Personal data
Comment text is written by the public, and people put contact details in it. Email addresses, and runs of
10 to 13 digits that look like a phone number, are removed from the text and the author name before
anything is stored ([email removed], [phone removed]). That covers the international and mobile forms
this Actor was tested against; it is not a guarantee that every national phone format is caught. Channel
handles and channel ids are kept - they are the public identity YouTube shows next to the comment. Links
that commenters put in their text are left as they are.
How the numbers in this README can be checked
Everything above was measured, not estimated, and the responses are in test/fixtures/ so you can count
them yourself:
npm test # checks against those real responses, including the numbers quoted abovenpm run mutate # deliberate breakages; every one of them must turn the checks red
The counts in this README are themselves asserted by the test suite, so a number that drifts away from the fixtures turns the checks red instead of quietly becoming a false claim.