YouTube Comments Scraper avatar

YouTube Comments Scraper

Pricing

from $0.35 / 1,000 comments

Go to Apify Store
YouTube Comments Scraper

YouTube Comments Scraper

Scrape YouTube comments and their replies with no API key or quota. Returns comment text, author name and channel, like count, reply count, publish time, and pinned or creator-hearted markers. Sort by top or newest using YouTube's own ordering, and page as deep as you need.

Pricing

from $0.35 / 1,000 comments

Rating

0.0

(0)

Developer

Superslow Sloth

Superslow Sloth

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

Scrapes the comment section of YouTube videos in bulk. Give it a list of videos and it returns one row per comment, with the author, the like count, the published time, and the pin and heart markers the site shows.

Input

FieldTypeNotes
videoIdsarrayBare IDs, watch URLs, youtu.be links, or /shorts/ links. Mixed input is fine.
maxCommentsintegerPer video, default 100. Replies count towards this budget when enabled.
sortBystringtop (default) or newest. This selects YouTube's own sort, not a local re-sort.
includeRepliesbooleanOff by default. Expands the reply thread under each top-level comment.
proxyConfigurationobjectRecommended. YouTube refuses datacenter addresses with a bot check.

Output

One dataset item per comment:

{
"comment_id": "Ugzge340dBgB75hWBm54AaABAg",
"video_id": "dQw4w9WgXcQ",
"text": "can confirm: he never gave us up",
"author_name": "@YouTube",
"author_channel_id": "UCBR8-60-B28hp2BmDPdntcQ",
"author_avatar_url": "https://yt3.ggpht.com/...=s88-c-k-c0x00ffffff-no-rj",
"author_is_verified": true,
"author_is_creator": false,
"like_count_text": "305K",
"like_count": 305000,
"published_time_text": "1 year ago",
"is_reply": false,
"parent_comment_id": null,
"is_hearted": true,
"hearted_by": "❤ by @RickAstleyYT",
"is_pinned": true,
"pinned_by_text": "Pinned by @RickAstleyYT",
"reply_count_text": "963",
"reply_count": 963
}

Replies carry is_reply: true and parent_comment_id set to the id of the top-level comment they answer.

What the source does and does not give

  • Like counts are abbreviated at the source. YouTube renders 305K, never the exact number. like_count_text is that string verbatim and like_count is it expanded, so anything above a thousand is rounded by YouTube before we ever see it. The exact figure is not available at any public endpoint.
  • Published times are relative. published_time_text is "1 year ago", which is all the response carries. No absolute timestamp is exposed, so none is invented.
  • There is no separate "channel owner liked" signal. YouTube's creator acknowledgement is the heart, and that is what is_hearted and hearted_by report. A comment can be pinned without being hearted and the other way round, so both markers are emitted separately.
  • Anything missing is null, never 0 and never "". A zero in a dataset reads as a measurement.
  • Comments turned off is a normal outcome, not an error. The video is skipped, the reason is written to the run log, and nothing is charged for it. The same holds for videos that no longer exist.

Charging

One comment-scraped event per comment after it has been written to the dataset, plus one actor-start per run. Comment ids are de-duplicated across pages before anything is charged, so a comment repeated by YouTube across a page boundary is never billed twice.

How it works

Comments are not on the watch page. They come from YouTube's InnerTube next endpoint in two steps: the first response for a video carries only a continuation token, hidden in the itemSectionRenderer whose sectionIdentifier is comment-item-section; posting that token back to the same endpoint returns the first page of comments and the token for the next. The sort submenu in the comment engagement panel supplies a different starting token for top and for newest, which is how sortBy is honoured.

If YouTube changes that shape, the live contract test under tests/contract/ is what will say so.