YouTube Comments Scraper - Comments, Replies, Likes & Authors avatar

YouTube Comments Scraper - Comments, Replies, Likes & Authors

Pricing

from $1.46 / 1,000 comment returneds

Go to Apify Store
YouTube Comments Scraper - Comments, Replies, Likes & Authors

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

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

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, and commentUrl - a link that opens that exact comment on YouTube
  • The author: authorName, authorChannelId, authorChannelUrl, authorIsVerified, authorIsArtist, and authorIsChannelOwner (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), and isEdited split out of the text instead of glued to it
  • The status flags: isPinned with pinnedText, hasCreatorHeart, isReply, replyLevel, parentCommentId
  • The video: videoId, videoUrl, videoTitle, and videoCommentCount - 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.be links, 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) or newest.
  • includeReplies and maxRepliesPerComment - replies come back as their own rows with parentCommentId and replyLevel: 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:

statuswhen
comments-disabledYouTube refuses to serve a comment section for this video
invalid-inputsomething you passed is not a YouTube video URL or video ID
no-new-since-last-runmonitoring mode: everything read had already been returned to you
sort-unavailableYouTube did not offer the comment order you asked for on that video
video-unavailablethe ID is wrong, or the video is private, deleted or blocked here
no-resultsthe comment section loaded and was empty
partial-coverageyou got fewer comments than the video claims, and why the run stopped
unreadablethe answer could not be read - the video page is retried 3 times first
bot-checkYouTube answered with a bot check instead of comments
no-matchcomments were read but none matched your filters
request-limit-reachedthe run stopped at your maxRequests
maximum-reachedrows were left out by your maxRecords
budget-reachedthe 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 above
npm 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.