YouTube Channel Scraper With Comments avatar

YouTube Channel Scraper With Comments

Pricing

from $3.99 / 1,000 results

Go to Apify Store
YouTube Channel Scraper With Comments

YouTube Channel Scraper With Comments

Scrape complete YouTube channel data with ease. This actor gathers videos, stats, descriptions, tags, and publishing details from any public channel. Built for analysts, marketers, and developers needing reliable YouTube data for research or monitoring.

Pricing

from $3.99 / 1,000 results

Rating

0.0

(0)

Developer

Scrapio

Scrapio

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

1

Monthly active users

2 days ago

Last modified

Share

YouTube Channel Scraper — Extract Videos, Shorts and Comments

youtube-channel-scraper-with-comments is a YouTube channel scraper that walks a channel's Videos, Shorts, Live and Community tabs and returns one dataset row per item — then opens every collected video's comment section and returns each comment as its own linked row. Unlike scraping frameworks that return raw HTML, it returns typed JSON — exact view counts, absolute publish dates, and comment text with author identity, like labels, reply counts, pinned and creator-heart flags — ready for a database, a dashboard or an LLM context window without any parsing. This guide covers every field the Actor writes and how teams run it in production: enrichment pipelines, scheduled monitoring, and bulk dataset builds.


🧭 What Does youtube-channel-scraper-with-comments Do?

youtube-channel-scraper-with-comments points at one or more YouTube channels — by URL, @handle, or bare UC… channel ID — and reads the channel's About, Videos, Shorts, Live and Community tabs the same way a logged-out browser would. No YouTube account, no Google API key, no OAuth. Every long-form video, Short and live/past stream it collects can then be joined to its own comment thread: each comment (and, optionally, each reply) comes back as an additional dataset row tagged with the parent video's id.

  • 🏠 Channel profile — description, join date, country, subscriber label, lifetime views and video count, avatar, banner, external links, verification badge
  • 🎬 Long-form videos — from the Videos tab, in the sort order YouTube itself offers
  • 📱 Shorts — from the Shorts tab, with duration recovered from the player where the grid does not show one
  • 🔴 Live and past streams — from the Live tab, with concurrent-viewer text while a stream is live
  • 💬 Community posts — text, image, poll and video/playlist attachments, with the attachment kind reported in postType
  • 💬 Comment threads — one row per comment, with optional reply threads, on any mix of videos, Shorts and live streams
  • 📈 Exact numbers, not rounded ones2,291,746 instead of 2.2M, and YouTube's own absolute publish date instead of 5 days ago

⚡ Features & Capabilities

The Actor's feature set splits into channel-surface coverage and the comment/audience layer on top of it.

Core features

  • One dataset row per entity — rowType is always one of channel, video, short, livestream, post, comment. No column is ever named after an input value, so the table shape never changes with what you scrape.
  • Comment rows carry isChild: true and parentId set to the parent video's id, so a single dataset holds the full channel-plus-audience graph without a second run.
  • Exact viewCount and likesCount pulled from YouTube's own InnerTube /player and /next endpoints — never derived from an abbreviated label like 2.2M.
  • Comment identity fields straight from YouTube's response: authorName, authorHandle, authorChannelId, authorChannelUrl, authorAvatarUrl, authorIsVerified, authorIsChannelOwner, authorIsArtist.
  • Creator signals most scrapers skip: isPinned / pinnedByText and isHeartedByCreator — which comments the channel actually pinned or hearted.
  • commentsStatus distinguishes ok, disabled (no comment section) and fetch-failed (the request itself failed) — a video with comments off is never reported as a video with zero comments.

How this Actor compares to other ways to get YouTube channel data

There is no public Apify Store competitor identified for this comparison at the time of writing, so the table below compares against the two realistic alternatives — the official API and rolling your own HTML/InnerTube parser — rather than a named product.

Featureyoutube-channel-scraper-with-commentsYouTube Data API v3Custom HTML/InnerTube scraping
Setup✅ No account, no API key❌ Google Cloud project, API key, metered daily quota❌ Build and maintain your own client
Output format✅ Typed JSON, one row per item✅ JSON, but stitched from several separate endpoints❌ Raw HTML / undocumented InnerTube JSON
Exact view count on comment fetch✅ Free — same request that reads comments➖ Available via a separate call❌ Requires reverse-engineering the player response
Reply threads✅ Optional, capped per thread✅ Via commentThreads.list❌ Requires reverse-engineering continuation tokens
Front-end change resilience✅ Actor maintained against layout changes✅ Stable, versioned contract❌ Breaks on every markup change
Request ceilingDocumented input caps (see Input Parameters)Metered daily quotaSelf-managed, undocumented

If your use case is feeding structured data to an LLM, the output-format row is the decision-maker — passing raw HTML into an agent loop is a reliability failure mode, not a feature; a stable JSON schema is not.

When another tool might suit you better

If you already have Google Cloud access and only need a channel's statistics or a small number of comment pages within your daily quota, the official YouTube Data API v3 is a reasonable fit — it is a versioned, officially supported contract and needs no proxy. It becomes a worse fit once you need exact view counts joined to comments in one call, Shorts/Live/Community coverage, or a request volume that would burn through a metered quota quickly.

youtube-channel-scraper-with-comments within the Scrapio data stack

youtube-channel-scraper-with-comments covers a channel's own content plus the comments underneath it. For a video's most-replayed heatmap and engagement peaks across a channel or playlist, use Youtube Most Replayed Scraper. For discovering videos by hashtag, keyword or handle with full (untruncated) descriptions and exact upload dates, use Youtube Video Scraper by Hashtag.


Why do developers and data teams scrape YouTube channels?

Different teams pull different slices of the same channel-plus-comment graph.

🏢 Competitive and content intelligence

Marketing and content teams point startUrls at competitor or peer channels, cap maxResults to the newest uploads, and pull title, viewCount, publishedAt and duration to track upload cadence and which formats are landing. Layering commentCountTotal and commentsCollected on top shows which uploads are actually generating audience reaction, not just views.

📊 AI training data and RAG indexing

text (comment body), channelDescription and textContent (community posts) are the high-information natural-language fields — they are what you'd chunk into a RAG index for "what are viewers of this channel saying" or "what is this creator's audience talking about." For training data, viewCount, likesCount, replyCount and commentCountTotal are exact integers wherever YouTube publishes an exact figure, with viewCountText / likeCountText shipped alongside as the fallback when it doesn't — every field returns as a typed primitive, so no normalization pass is needed before either use case.

📱 Social listening and sentiment tracking

text, authorName, likeCountText and publishedAtEstimated let you track what viewers say under new uploads as it's posted, and isHeartedByCreator / isPinned show which of those reactions the channel itself amplified.

🔬 Research and academic use

commentsSortedBy, replyLevel and commentCountTotal support studies of thread structure and engagement distribution on public channels. This Actor returns only what is publicly visible on a channel's own tabs — there is no login-gated or private content in scope.

🎥 Product and SaaS development

Channel analytics dashboards, creator-monitoring tools and comment-moderation aids can be built directly on the channel, video/short/livestream and comment row shapes without a translation layer, since every run returns the same stable column set regardless of which channels were scraped.


🍚 Input Parameters

All 16 parameters, read directly from .actor/actor.json. Only startUrls is required.

ParameterRequiredTypeDescriptionExample Value
startUrlsYesarray (string list)Channel URLs (https://www.youtube.com/@Handle or .../channel/UC…), bare @handles, or bare UC… channel IDs. One per line. Keyword search is not supported — every entry must resolve to a channel. Default ["https://www.youtube.com/@MrBeast"]["https://www.youtube.com/@MKBHD"]
maxResultsNointeger, min 1, max 1000Upper limit for each enabled section (videos, Shorts, live streams, posts) on each channel. Comments have their own cap and never eat this budget. Default 1025
sortOrderVideosNostring enum: date (Latest), viewCount (Popular), oldest (Oldest)Which of YouTube's own Videos-tab sort chips to use. Channels that do not offer Popular/Oldest chips fall back to newest-first, and the run log says so. Shorts, Live and Community have no sort chips at all, so those tabs are always newest-first. Default dateviewCount
scrapeChannelInfoNobooleanEmit one channel row per channel: description, join date, country, subscriber text, lifetime view count, video count, avatar, banner, external links and verification badge. Default truetrue
scrapeVideosNobooleanEmit one video row per upload from the Videos tab. Default truetrue
scrapeShortsNobooleanEmit one short row per Short. Channels without a Shorts tab return no Shorts rows. Default truetrue
scrapeLiveStreamsNobooleanEmit one livestream row per item on the Live tab. Channels without a Live tab return no livestream rows. Default truetrue
scrapePostsNobooleanEmit one post row per community post, including image, poll and video attachments. Default truetrue
videoCommentsNobooleanFetch the comments under every collected item. Each comment becomes its own row with rowType: "comment", isChild: true and the video id in parentId. Default truetrue
commentSourcesNoarray, enum items: videos, shorts, liveStreamsWhich sections to read comments on. Every extra source multiplies the request count. Default ["videos"]["videos", "shorts"]
maxCommentsPerVideoNointeger, min 1, max 500YouTube serves 20 comments per request, so 20 = one request, 100 = five. Replies are counted separately. Default 2050
commentsSortByNostring enum: top (Top comments), newest (Newest first)Exactly the two orders YouTube itself offers. Default topnewest
includeCommentRepliesNobooleanAdds one request per commented-on thread. Replies come back as rows too, with parentCommentId set and replyLevel: 1. Default falsefalse
maxRepliesPerCommentNointeger, min 1, max 100Cap on replies kept per thread when reply following is on. Default 1010
exactVideoStatsNobooleanReads the watch endpoint for YouTube's own absolute publish date and exact view figure, instead of a relative label like 5 days ago. Free when comments are on — it is the same request. Default truetrue
proxyConfigurationNoobject (proxy editor)Apify Proxy attached to every request, channel pages and comment pages alike. Default {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US"}see below
{
"startUrls": ["https://www.youtube.com/@MKBHD"],
"maxResults": 25,
"sortOrderVideos": "date",
"scrapeChannelInfo": true,
"scrapeVideos": true,
"scrapeShorts": true,
"scrapeLiveStreams": true,
"scrapePosts": true,
"videoComments": true,
"commentSources": ["videos", "shorts"],
"maxCommentsPerVideo": 50,
"commentsSortBy": "top",
"includeCommentReplies": false,
"maxRepliesPerComment": 10,
"exactVideoStats": true,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"],
"apifyProxyCountry": "US"
}
}

Supported URL types and input formats

startUrls accepts three shapes, normalized to a canonical channel URL before any request is made:

  • Full channel URL, with or without a tab suffix — https://www.youtube.com/@MKBHD, https://www.youtube.com/@MKBHD/videos, https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ. Legacy /c/… and /user/… paths are also accepted.
  • Bare @handle@MKBHD or MKBHD (the @ is added automatically).
  • Bare channel ID — a 24-character UC… string.

Anything that is not one of the three (a search term, a video URL, a playlist URL) is skipped with a warning in the run log — this Actor resolves channels, it does not search for them.


📦 Output Format

Every row is typed, normalized JSON with a stable column set — the schema does not change based on which channels or how many items you scraped. Results are written to the Actor's default dataset and can be exported from the Apify Console as JSON, CSV, Excel, XML, RSS or HTML, or read back with the Apify API / apify_client in JSON or JSONL.

Output for video, Short and livestream rows

{
"rowType": "video",
"channelId": "UCBJycsmduvYEL83R_U4JriQ",
"channelName": "Marques Brownlee",
"channelUsername": "@mkbhd",
"channelUrl": "https://www.youtube.com/@mkbhd",
"numberOfSubscribers": "21.1M subscribers",
"inputUrl": "https://www.youtube.com/@MKBHD",
"scrapedAt": "2026-08-04T09:12:03+00:00",
"order": 1,
"title": "Galaxy Z Fold 8 Review: Honeymoon's Over",
"url": "https://www.youtube.com/watch?v=Z6z_feacXW8",
"videoId": "Z6z_feacXW8",
"duration": "11:36",
"thumbnailUrl": "https://i.ytimg.com/vi/Z6z_feacXW8/hqdefault.jpg",
"viewCount": 2291746,
"viewCountText": "2.2M views",
"likesCount": 70579,
"publishedTimeText": "1 day ago",
"publishedAt": "2026-08-03T17:05:00-07:00",
"publishedDateText": "Aug 3, 2026",
"isChild": false,
"parentId": null,
"parentType": null,
"commentsEnabled": true,
"commentsStatus": "ok",
"commentCountText": "4,237 Comments",
"commentCountTotal": 4237,
"commentsCollected": 50,
"commentsSortedBy": "top",
"commentsSortApplied": true
}

A livestream row carries three more fields the same request already returns: isLive (boolean), isUpcoming (boolean) and concurrentViewersText (the "N watching" label while a stream is live).

Output for comment rows

{
"rowType": "comment",
"channelId": "UCBJycsmduvYEL83R_U4JriQ",
"channelName": "Marques Brownlee",
"channelUsername": "@mkbhd",
"channelUrl": "https://www.youtube.com/@mkbhd",
"numberOfSubscribers": "21.1M subscribers",
"inputUrl": "https://www.youtube.com/@MKBHD",
"scrapedAt": "2026-08-04T09:12:03+00:00",
"isChild": true,
"parentId": "Z6z_feacXW8",
"parentType": "video",
"order": 0,
"title": "Finally, a 70mm IMAX phone",
"url": "https://www.youtube.com/watch?v=Z6z_feacXW8&lc=Ugyhzy3WgpSk-QKQF2h4AaABAg",
"commentId": "Ugyhzy3WgpSk-QKQF2h4AaABAg",
"videoId": "Z6z_feacXW8",
"videoTitle": "Galaxy Z Fold 8 Review: Honeymoon's Over",
"videoUrl": "https://www.youtube.com/watch?v=Z6z_feacXW8",
"commentUrl": "https://www.youtube.com/watch?v=Z6z_feacXW8&lc=Ugyhzy3WgpSk-QKQF2h4AaABAg",
"text": "Finally, a 70mm IMAX phone",
"publishedTimeText": "1 day ago",
"publishedAtEstimated": "2026-08-03T09:12:07+00:00",
"publishedAtPrecision": "day",
"likeCountText": "4.2K",
"replyCountText": "17",
"replyCount": 17,
"replyLevel": 0,
"isReply": false,
"parentCommentId": null,
"authorName": "@jameseze9469",
"authorHandle": "@jameseze9469",
"authorChannelId": "UCjBCXe6qFrtxfsPR-ZU0j9A",
"authorChannelUrl": "https://www.youtube.com/channel/UCjBCXe6qFrtxfsPR-ZU0j9A",
"authorAvatarUrl": "https://yt3.ggpht.com/ytc/AIdro_example=s176-c-k-c0x00ffffff-no-rj",
"authorIsVerified": false,
"authorIsChannelOwner": false,
"authorIsArtist": false,
"isPinned": false,
"pinnedByText": null,
"isHeartedByCreator": false,
"commentsSortedBy": "top",
"viewCount": null,
"viewCountText": null,
"commentsEnabled": null,
"commentsStatus": null,
"commentCountText": null,
"commentCountTotal": null,
"commentsCollected": null,
"commentsSortApplied": null,
"publishedDateText": null
}

A top-level comment that was expanded for replies (includeCommentReplies: true) also carries repliesCollected — the number of reply rows kept for that thread.

Output for channel profile rows

{
"rowType": "channel",
"channelId": "UCBJycsmduvYEL83R_U4JriQ",
"channelName": "Marques Brownlee",
"channelUsername": "@mkbhd",
"channelUrl": "https://www.youtube.com/@mkbhd",
"numberOfSubscribers": "21.1M subscribers",
"inputUrl": "https://www.youtube.com/@MKBHD",
"scrapedAt": "2026-08-04T09:12:03+00:00",
"order": 1,
"title": "Marques Brownlee",
"url": "https://www.youtube.com/@mkbhd",
"channelDescription": "MKBHD ... The quality of the video and audio equipment ...",
"channelJoinedDate": "Mar 21, 2008",
"channelLocation": "United States",
"channelAvatarUrl": "https://yt3.ggpht.com/example-avatar=s800-c-k-c0x00ffffff-no-rj",
"channelBannerUrl": "https://yt3.googleusercontent.com/example-banner=w1707-fcrop64=1",
"channelDescriptionLinks": [
{ "text": "Twitter", "url": "https://twitter.com/mkbhd" },
{ "text": "Instagram", "url": "https://instagram.com/mkbhd" }
],
"channelTotalVideos": 1874,
"channelTotalVideosText": "1,874 videos",
"channelTotalViews": 5123456789,
"viewCountText": "5,123,456,789 views",
"isChannelVerified": true,
"availableTabs": ["Home", "Videos", "Shorts", "Live", "Posts", "Playlists", "About"],
"isChild": false,
"parentId": null,
"parentType": null,
"viewCount": null,
"publishedTimeText": null,
"commentsEnabled": null,
"commentsStatus": null,
"commentCountText": null,
"commentCountTotal": null,
"commentsCollected": null,
"commentsSortedBy": null,
"commentsSortApplied": null,
"publishedDateText": null
}

Output for community post rows

{
"rowType": "post",
"channelId": "UCBJycsmduvYEL83R_U4JriQ",
"channelName": "Marques Brownlee",
"channelUsername": "@mkbhd",
"channelUrl": "https://www.youtube.com/@mkbhd",
"numberOfSubscribers": "21.1M subscribers",
"inputUrl": "https://www.youtube.com/@MKBHD",
"scrapedAt": "2026-08-04T09:12:03+00:00",
"order": 1,
"title": "Alright, it's that time: https://vote.mkbhd.com ...",
"url": "https://www.youtube.com/post/UgkxX6gkDxQ0KRucvyG7NLui0LhjHp0CLlfZ",
"postId": "UgkxX6gkDxQ0KRucvyG7NLui0LhjHp0CLlfZ",
"postType": "image",
"textContent": "Alright, it's that time: https://vote.mkbhd.com ...",
"imageUrls": ["https://yt3.ggpht.com/example-post-image=s0"],
"pollOptions": [],
"pollTotalVotesText": null,
"attachedVideoId": null,
"likesCount": 11964,
"likesCountText": "11K",
"commentsCountText": "1K",
"publishedTimeText": "2 years ago (edited)",
"isChild": false,
"parentId": null,
"parentType": null,
"viewCount": null,
"viewCountText": null,
"commentsEnabled": null,
"commentsStatus": null,
"commentCountText": null,
"commentCountTotal": null,
"commentsCollected": null,
"commentsSortedBy": null,
"commentsSortApplied": null,
"publishedDateText": null
}

Schema stability and export options

Column names stay fixed across runs and across YouTube front-end redesigns — the Actor parses YouTube's current lockupViewModel grid format with videoRenderer / gridVideoRenderer kept as a fallback, so a YouTube layout change is absorbed inside the parser rather than surfacing as a renamed or missing dataset column. Every field documented above is either filled from a measured source or left explicitly null — never estimated or invented. Export the dataset as JSON, JSONL, CSV, Excel, XML, RSS or HTML from the Apify Console, or pull it programmatically with the Apify API or apify_client.


💡 youtube-channel-scraper-with-comments Strategy Guide

🎯 Strategy 1: Real-time enrichment pipeline

Trigger a run whenever a new channel enters your CRM or lead list: pass its URL as the sole entry in startUrls, set maxResults low (you only need the newest uploads to gauge activity), and turn videoComments on with a small maxCommentsPerVideo. Read back numberOfSubscribers, channelTotalVideos, publishedAt on the newest video and commentCountTotal, then write those fields onto the lead record in your CRM or data warehouse as an activity/engagement score.

🎯 Strategy 2: Scheduled monitoring and alerting

Use an Apify Schedule to run the Actor daily against a fixed startUrls list of channels you track. Diff each run's channelTotalVideos, viewCount on the latest video, and commentCountTotal against the previous run's dataset (queried via the Apify API by run id or dataset id) and alert when a tracked channel posts a new upload or a video's comment count jumps past a threshold you define. The Actor itself has no built-in diffing or webhook-on-change feature — that comparison logic lives in your own pipeline.

🎯 Strategy 3: Bulk dataset build

For a research or training corpus across many channels, feed a large startUrls list to a single run (Apify Proxy attaches automatically to every request) or fan out one run per channel via the Apify API for parallelism, then aggregate the resulting datasets into your warehouse. maxResults (ceiling 1000) and maxCommentsPerVideo (ceiling 500) are hard input caps enforced in the Actor's own code — plan corpus size around them rather than assuming an unbounded pull per channel.

Strategy comparison at a glance

StrategyBest forRun patternOutput format
Real-time enrichmentLead/CRM scoring on new channelsTriggered, single-channel runJSON row appended to your record
Scheduled monitoringTracking a fixed watchlist over timeApify Schedule, recurring runDataset diffed run-over-run
Bulk dataset buildResearch / training corporaLarge startUrls list or fan-out runsAggregated CSV / database load

Other Scrapio YouTube scrapers

ScraperWhat it extracts
Youtube Most Replayed ScraperMost Replayed heatmap, replay peaks, and video stats for every video in a channel or playlist
Youtube Video Scraper by HashtagVideos by hashtag, keyword or @handle, with full descriptions and exact ISO upload dates

Cross-platform creator and comment data

ScraperWhat it extracts
Tiktok Data ScraperTikTok profiles, videos, comments and replies, with optional AI sentiment/topic classification
Threads Search Post ScraperThreads posts with engagement analytics

How to integrate youtube-channel-scraper-with-comments with your stack

youtube-channel-scraper-with-comments works with any language or tool that can make an HTTP request — the Apify API and apify_client SDKs are the two most common paths.

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
run_input = {
"startUrls": ["https://www.youtube.com/@MKBHD", "https://www.youtube.com/@veritasium"],
"maxResults": 20,
"videoComments": True,
"maxCommentsPerVideo": 50,
"commentsSortBy": "top",
}
run = client.actor("scrapio/youtube-channel-scraper-with-comments").call(run_input=run_input)
import csv
items = client.dataset(run["defaultDatasetId"]).list_items().items
with open("channel_and_comments.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=sorted({k for row in items for k in row}))
writer.writeheader()
writer.writerows(items)
print(f"Wrote {len(items)} rows")

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_API_TOKEN>' });
const run = await client.actor('scrapio/youtube-channel-scraper-with-comments').call({
startUrls: ['https://www.youtube.com/@MKBHD'],
maxResults: 20,
videoComments: true,
maxCommentsPerVideo: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Fetched ${items.length} rows`);

Async and scheduled pipelines

For large startUrls lists, call the Actor with .call() (or the async run API) and poll run.status / use a webhook on the Apify platform to be notified when the run finishes, rather than holding a connection open. For recurring monitoring, set up an Apify Schedule against a fixed input and read the resulting dataset id from each scheduled run via the API.


🎯 Who Needs youtube-channel-scraper-with-comments? (Use Cases & Industries)

🏢 Marketing and competitive intelligence teams

A brand team tracking three competitor channels runs the Actor weekly, reads title, publishedAt, viewCount and commentCountTotal for the newest uploads, and reports which formats and posting cadence are driving the most audience reaction.

📊 AI / RAG engineers

A support or research assistant indexes text from comments and channelDescription from the channel row into a vector store, so it can answer "what does this channel's audience think about X" grounded in real, dated viewer comments rather than a static training-data snapshot.

📱 Social listening analysts

An analyst monitoring brand mentions in comments filters rowType: "comment" rows for keyword matches in text, tracks authorName and likeCountText to gauge reach, and flags anything isHeartedByCreator or isPinned as creator-endorsed sentiment.

🔬 Researchers

Academic researchers studying platform discourse pull commentsSortedBy, replyLevel and commentCountTotal across a sample of public channels to study thread structure and engagement distribution — all from data already visible to any logged-out visitor.

🎥 Product and SaaS builders

Teams building a creator-analytics or comment-moderation product ingest the stable channel / video / comment row shapes directly into their own schema, without writing a YouTube HTML parser first.


Scraping publicly accessible YouTube pages is generally lawful; what you do with the personal data inside comments is where legal obligations attach. Courts have distinguished scraping public data from unauthorized-access claims — in hiQ Labs, Inc. v. LinkedIn Corp., 9th Cir. 2019 (reaffirmed on remand, 2022), the Ninth Circuit held that scraping data a website makes publicly available does not, by itself, violate the Computer Fraud and Abuse Act. That reasoning concerns public-data access, not YouTube's own Terms of Service.

Three separate questions apply here:

  • Scraping public data — channel pages, video listings and comment sections that any logged-out visitor can see are public. Precedent generally supports accessing such data.
  • Violating YouTube's Terms of Service — YouTube's ToS restricts automated access. Breaching it is a contractual/civil matter between you and YouTube, not a criminal one, but it can carry consequences such as IP or account blocks.
  • Data protection obligations — comment rows carry personal data about individual commenters (authorName, authorHandle, authorChannelId, authorAvatarUrl), and channel rows carry the channel owner's public identity. Where GDPR, CCPA or similar laws apply to you or your data subjects, you — not the Actor — are the data controller for anything you store or process, and lawful basis, retention limits and any deletion requests are your responsibility.

youtube-channel-scraper-with-comments returns only publicly accessible data. What you do with that data is your responsibility — consult legal counsel for commercial applications involving personal data.


❓ Frequently asked questions

Does youtube-channel-scraper-with-comments work without a YouTube account?

Yes. Every surface it reads — the channel tabs and the InnerTube browse, player and next endpoints — answers while logged out. No account, cookie, or Google API key is required.

How does it handle YouTube's anti-scraping measures?

It runs every request through Apify Proxy (US residential by default), carries YouTube's own CONSENT/SOCS cookies to avoid the consent interstitial, and retries a channel once on a fresh proxy session if the first attempt fails with zero rows pushed. Exact-count lookups that get bot-walled are individually retried on a fresh proxy session before the field is left null. It does not render a browser — every request is a direct HTTP call to YouTube's own page and InnerTube endpoints.

Can I run it at scale without getting blocked?

The Actor enriches up to 8 video-type items and reads up to 4 comment threads concurrently per channel, and caps outbound connections per run at 30. There is no published uptime or success-rate figure — reliability depends on your proxy configuration, and datacenter IPs are more likely to hit a consent or bot interstitial than residential ones.

How fresh is the data youtube-channel-scraper-with-comments returns?

Every run fetches live from YouTube at the time it executes — nothing is cached or served from a prior run. scrapedAt on every row records exactly when that fetch happened.

Which fields work best for AI training and RAG indexing?

For RAG: text (comment body), channelDescription and textContent (community posts) are the high-information natural-language fields. For training data: viewCount, likesCount, replyCount and commentCountTotal are exact integers with consistent structure wherever YouTube publishes an exact figure. Every field returns as a typed primitive — string, integer, boolean or array — so no normalization is needed before either use case.

Does the Actor collect personal data, and what am I responsible for?

Yes — comment rows include commenter identity fields (authorName, authorHandle, authorChannelId, authorAvatarUrl). This is publicly visible data pulled from public comment sections. Storing or processing it under GDPR, CCPA or similar laws makes you the data controller for that data; the Actor performs no anonymization or consent handling on your behalf.

Does youtube-channel-scraper-with-comments work with Claude, ChatGPT and other AI agent tools?

There is no MCP server for this Actor. It is callable as a standard HTTP endpoint through the Apify API or apify_client/apify-client SDKs from any agent framework — every response is typed JSON, so it can be passed into an LLM context window without a parsing step.

Can I limit comments to just Shorts or just live streams?

Yes — commentSources accepts any combination of videos, shorts and liveStreams. Leaving it at the default ["videos"] skips comment requests for Shorts and live streams entirely, which is the cheapest configuration when you only need long-form video comments.

What happens on a channel with no Shorts, Live or Community tab?

The Actor detects the tab YouTube actually served (it silently serves the Home feed at /streams and /shorts for channels without those tabs) and returns zero rows for that section rather than mislabeling Home-feed videos as Shorts or live streams.

How does youtube-channel-scraper-with-comments compare to other ways to get YouTube data?

No specific Apify Store competitor was identified for a like-for-like comparison at the time of writing. Against the realistic alternatives: it needs no API key or quota management the way the YouTube Data API v3 does, and it returns a stable typed schema the way a hand-built HTML parser does not — at the cost of depending on Apify Proxy for reliability at volume, the way an officially supported API does not.


ℹ️ Disclaimer

youtube-channel-scraper-with-comments extracts only publicly available data from YouTube. This tool is intended for lawful use cases only. Users are responsible for complying with YouTube's Terms of Service and applicable data protection laws in their jurisdiction, including any obligations that attach to personal data found in comment author fields.