YouTube Comments Scraper With Reply Thread Expansion
Pricing
from $3.99 / 1,000 results
YouTube Comments Scraper With Reply Thread Expansion
YouTube Comments Scraper extracts YouTube comments with reply thread expansion, including comment text, authors, timestamps, likes, reply counts, nested replies, and video details. Ideal for sentiment analysis, audience research, engagement tracking, and content insights.
Pricing
from $3.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapio
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
YouTube Scraper — Extract Comments, Reply Threads and Commenter Data
YouTube Comments Scraper With Reply Thread Expansion pulls top-level comments, fully expanded reply threads, and commenter data (handle, avatar, verified/creator badges, like counts) from any public YouTube video — returned as clean, typed JSON. Unlike scraping frameworks that return raw HTML, it returns structured records ready for your database, spreadsheet, or LLM pipeline without any parsing. What sets it apart from a standard comment exporter is that it follows each parent comment's own "more replies" continuation token, recovering the full thread instead of the 2-3 replies YouTube previews inline. This guide covers every input and output field and how teams deploy it for moderation, sentiment analysis, and dataset building.
🧭 What Does YouTube Comments Scraper With Reply Thread Expansion Do?
This Actor takes one or more YouTube video URLs (or bare video IDs) and scrapes every top-level comment plus, optionally, every reply hiding behind "View N more replies." No YouTube account or login is required — the Actor fetches public video pages and the same /youtubei/v1/next endpoint YouTube's own web client uses, so it only ever sees what an anonymous visitor can see.
- Scrapes top-level comments and fully expanded reply threads in one run
- Follows each parent comment's own reply-continuation token rather than relying on YouTube's inline preview (which now ships 0 real reply objects, only a "load more" token)
- Returns commenter data on every row: handle, avatar URL, channel-owner flag, verified badge, like count, creator-heart flag
- Filters rows by keyword (include and exclude) across the entire thread — comments and replies alike
- Sorts top-level comments by "top" (most liked) or "newest"
- Bulk-processes multiple videos in a single run
- Auto-escalates through no-proxy → datacenter → residential proxy tiers on a block
⚡ Features & Capabilities
The Actor's feature set splits into thread-expansion mechanics, keyword filtering, and honest field labeling — each covered below.
Core features
- Full reply-thread pagination — follows every parent comment's own
continuationCommandtoken via the/youtubei/v1/nextendpoint until YouTube stops returning new replies,maxRepliesPerCommentis hit, or a 40-page-per-comment safety valve is reached (MAX_REPLY_PAGES_PER_PARENT = 40in source), so the run always terminates - Keyword include/exclude filtering —
includeKeywords/excludeKeywordsapply a case-insensitive substring match to every row'scommenttext, comments and replies alike, before the row is pushed (and billed) - Honest
isPinnedfield — pinned status is resolved independently fromrenderingPriority == 'RENDERING_PRIORITY_PINNED_COMMENT'on the comment thread, and no longer forcesauthorIsChannelOwner: truejust because a comment is pinned (a creator can pin any user's comment) - Correct
type/isChildlabeling — replies are labeled"reply"withisChild: true; parents are"comment"withisChild: false - Per-run child dataset mirror — every
isChild: truerow is also written to a separate dataset namedreplies-<runId>, so replies can be exported independently from top-level comments - 20 fields per row, including
cid,voteCount,replyCount,hasCreatorHeart,replyToCid,commentUrl, and an absolutescrapedAtUTC timestamp — see the full Output Format section below - Accepts full video URLs,
youtu.beshort links,/embed/URLs, or bare 11-character video IDs - Backward-compatible with the base YouTube Comments Scraper's input keys (
startUrls,maxComments,sortOrder, hiddenlanguage/region) so existing input JSON keeps working
YouTube Comments Scraper With Reply Thread Expansion within the Scrapio data stack
This Actor covers comments and reply threads. For channel-level subscriber/view/video growth tracking, use YouTube Channel Finder With Subscriber Counts. For retention heatmaps, chapter markers, and derived engagement-rate/view-velocity metrics on top of threaded comments, use YouTube Scraper With Comment & Engagement Analytics. For transcripts paired with view/like analytics, use YouTube Transcript Scraper With View & Like Analytics.
Why do developers and data teams scrape YouTube?
YouTube comment sections are one of the largest public repositories of unstructured audience reaction on the internet — the audiences below are the ones that actually pull this kind of data at volume.
🏢 Brand, community, and moderation teams
Community managers pull comment, author, voteCount, and replyCount to find the highest-engagement threads under a video and audit what's actually being said in the replies — not just the top-level comment a casual viewer sees. includeKeywords lets a team pull only rows mentioning a product or competitor name across an entire thread, including replies that never surface in YouTube's own UI without manually clicking through. isPinned and authorIsChannelOwner (now reported independently, not conflated) let moderation teams audit exactly which comments a creator chose to pin and which replies came from the creator versus fans.
📊 AI training data and RAG indexing
The comment field is the high-information text field here — full comment and reply bodies, already separated from HTML markup and YouTube's UI chrome, requiring no cleanup before embedding. For RAG, indexing comment alongside videoId, title, and publishedTimeText lets a retrieval system answer "what are people saying about video X" with attributable, sourced text. For training data, the consistent 20-field schema across both comments and replies (same keys, type and isChild distinguishing them) means a single parser handles the entire dataset without per-row branching.
📱 Competitive and market intelligence
Tracking voteCount and replyCount on comments mentioning a competitor's product across multiple videos surfaces which claims and complaints are actually resonating with an audience, not just which video got the most views. Running the Actor against a competitor's product-review or launch videos with includeKeywords set to a product name turns scattered public reaction into a structured feed a marketing or product team can track over time.
🔬 Research and academic use
Researchers studying online discourse, misinformation spread, or community dynamics use this Actor to pull complete conversation threads — including the reply layer most comment scrapers never reach — rather than the truncated top-level sample YouTube's page shows by default. This Actor only returns publicly accessible comments; it does not access private, age-restricted, or members-only content.
🎥 Product and SaaS development
Teams building sentiment dashboards, creator-analytics tools, or moderation-assist products use the Actor's JSON output as the raw feed behind their own enrichment layer, appending sentiment scores or spam classifiers on top of the comment, voteCount, and replyCount fields already provided.
🍚 Input Parameters
No input parameter is required — the Actor uses documented defaults for everything except videoUrls, which must be non-empty for a run to do anything.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
videoUrls | No | array | YouTube video URLs or bare 11-character IDs to scrape. Also accepts the base actor's startUrls key. | ["https://www.youtube.com/watch?v=KrLj6nc516A"] |
maxTopLevelComments | No | integer | Caps top-level (parent) comments scraped per video; replies are not counted against this. 0 = no limit. Default 50. Also accepts maxComments. | 50 |
commentSortOrder | No | string (enum: top, newest) | Order top-level comments are fetched in — top (most liked, YouTube default) or newest. Also accepts sortOrder. | "top" |
fetchAllReplies | No | boolean | When true (default), follows each parent's own reply-continuation token to recover the full thread. When false, only inline-preview replies are kept. | true |
maxRepliesPerComment | No | integer | Caps replies kept per parent when fetchAllReplies is on, counted after keyword filters. 0 = unlimited, up to a 40-page safety valve per comment. Default 50. | 100 |
includeKeywords | No | array | Case-insensitive substring match; only rows (comments and replies) containing at least one keyword are kept. Empty = keep everything. Default []. | ["giveaway"] |
excludeKeywords | No | array | Case-insensitive substring match; rows containing any keyword are dropped. Same full-thread scope as includeKeywords. Default []. | ["spam"] |
commentLanguage | No | string | Locale for YouTube's response; affects relative-date text like "2 years ago." Default en-GB. Also accepts hidden language key. | "en-US" |
commentRegion | No | string | Country code used for the request. Default US. Also accepts hidden region key. | "US" |
proxyConfiguration | No | object | Apify Proxy settings. No proxy by default; the Actor auto-escalates to datacenter then residential on a 403/429 block. | {"useApifyProxy": false} |
JSON input example:
{"videoUrls": ["https://www.youtube.com/watch?v=KrLj6nc516A", "dQw4w9WgXcQ"],"maxTopLevelComments": 50,"commentSortOrder": "top","fetchAllReplies": true,"maxRepliesPerComment": 100,"includeKeywords": [],"excludeKeywords": ["spam"],"commentLanguage": "en-GB","commentRegion": "US","proxyConfiguration": { "useApifyProxy": false }}
Supported URL types and input formats
The Actor's extract_video_id() parser accepts four input shapes in videoUrls, resolved in this order:
- Bare video ID — an 11-character alphanumeric string, e.g.
"dQw4w9WgXcQ" - Standard watch URL —
"https://www.youtube.com/watch?v=KrLj6nc516A" - Short link —
"https://youtu.be/KrLj6nc516A" - Embed URL —
"https://www.youtube.com/embed/KrLj6nc516A"
Mixed formats can be combined in the same videoUrls array. Any entry that fails to resolve to a valid video ID is skipped with a logged warning, and the rest of the run continues.
📦 Output Format
Every scraped row is a typed JSON object with a stable 20-key schema shared by both comments and replies — type and isChild are what distinguish them, not a different field set. Output is delivered through the Actor's Apify dataset, exportable in the formats Apify datasets support (JSON, CSV, Excel, XML, HTML table, RSS).
Output for Comments (top-level)
{"cid": "Ugzxs4_5UJwAI1xrNF14AaABAg","type": "comment","isChild": false,"isPinned": true,"publishedTimeText": "2 years ago","comment": "This trick actually works, tried it on my own channel last week!","author": "@TechReviewsDaily","avatar": "https://yt3.ggpht.com/ytc/AIdro_kJ3f8s9-example-avatar=s88-c-k-c0x00ffffff-no-rj","authorIsChannelOwner": true,"isVerified": true,"voteCount": 18900,"hasCreatorHeart": true,"replyCount": 764,"replyToCid": null,"videoId": "KrLj6nc516A","pageUrl": "https://www.youtube.com/watch?v=KrLj6nc516A","commentUrl": "https://www.youtube.com/watch?v=KrLj6nc516A&lc=Ugzxs4_5UJwAI1xrNF14AaABAg","title": "How I Doubled My Channel's Watch Time in 30 Days","commentsCount": 15500,"scrapedAt": "2026-07-25T12:00:00Z"}
Output for Reply Threads
Reply rows share the identical 20-key schema — the only structural difference is isChild: true, type: "reply", and a populated replyToCid linking back to the parent comment's cid:
{"cid": "Ugzxs4_5UJwAI1xrNF14AaABAg.9uj377Q6pSj9uj3Bb6-u_Y","type": "reply","isChild": true,"isPinned": false,"publishedTimeText": "2 years ago","comment": "Same here, subscriber count jumped after I tried this","author": "@GrowthWithJen","avatar": "https://yt3.ggpht.com/ytc/AIdro-example-avatar-2=s88-c-k-c0x00ffffff-no-rj","authorIsChannelOwner": false,"isVerified": false,"voteCount": 2100,"hasCreatorHeart": false,"replyCount": 0,"replyToCid": "Ugzxs4_5UJwAI1xrNF14AaABAg","videoId": "KrLj6nc516A","pageUrl": "https://www.youtube.com/watch?v=KrLj6nc516A","commentUrl": "https://www.youtube.com/watch?v=KrLj6nc516A&lc=Ugzxs4_5UJwAI1xrNF14AaABAg.9uj377Q6pSj9uj3Bb6-u_Y","title": "How I Doubled My Channel's Watch Time in 30 Days","commentsCount": 15500,"scrapedAt": "2026-07-25T12:00:00Z"}
Reply rows are also mirrored into a separate per-run dataset named replies-<runId>, so a downstream job can pull just the reply layer without filtering the main dataset by isChild.
Schema stability and export options
Field names are fixed by the Actor's row-building functions, not by whatever YouTube's front end happens to render that day — so the 20-key shape stays stable even as YouTube's internal page structure changes; the Actor already carries fallback parsing paths for two different YouTube comment renderer shapes (commentEntityPayload and legacy commentThreadRenderer) to absorb that kind of front-end drift without changing output keys. Every dataset row corresponds to exactly one billed row_result event — rows dropped by includeKeywords/excludeKeywords are filtered before the push, so filtered-out comments are never charged. Results export from the Apify dataset in JSON, CSV, Excel, XML, HTML table, or RSS, and are also readable programmatically via the Apify API or client SDKs.
💡 YouTube Comments Scraper With Reply Thread Expansion Strategy Guide
🎯 Strategy 1: Real-time enrichment pipeline
Trigger a run whenever a new video mention needs auditing — a brand-monitoring alert, a support ticket referencing a video, or a creator publishing a new upload. Run the Actor with that single videoUrls entry, then read the pushed rows' comment, author, voteCount, and replyToCid fields to enrich a CRM record or support ticket with "what's actually being said in the replies," not just the top comment. Because commentUrl is a direct deep link to the comment, the enrichment record can link straight back to the source for a human reviewer.
🎯 Strategy 2: Scheduled monitoring and alerting
Schedule recurring runs (via Apify's Schedule feature on the platform) against a fixed set of videoUrls — a channel's recent uploads, or videos already flagged for moderation. Diff each run's rows against the previous run on cid, voteCount, and replyCount: new cid values are new comments/replies since the last run, and a jump in voteCount on an existing cid signals a comment gaining traction. Pair with excludeKeywords to suppress known spam patterns before they ever reach the alerting layer.
🎯 Strategy 3: Bulk dataset build
Pass a large videoUrls array (or the base actor's startUrls key) in one run to build a research or training dataset across many videos; the Actor loops through the list sequentially within a single run, so for very large batches, split the URL list across multiple parallel runs launched via the Apify API rather than one oversized run. Aggregate the resulting datasets to CSV or a database using the Actor's own field schema — no reshaping needed since comments and replies share one 20-key shape.
Strategy comparison at a glance
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time enrichment | Single-video, on-demand lookups | One run per trigger event | JSON via dataset/API |
| Scheduled monitoring | Ongoing tracking of a fixed video/channel set | Recurring scheduled runs, diffed on cid/voteCount | JSON, diffed programmatically |
| Bulk dataset build | Large-scale research or training corpora | One run per URL batch, or multiple parallel runs | CSV/Excel export from dataset |
🌴 Related YouTube Scrapers & Tools
| Scraper Name | What it extracts |
|---|---|
| YouTube Channel Finder With Subscriber Counts | Per-channel subscriber, view, and video-count growth tracked across re-runs |
| YouTube Scraper With Comment & Engagement Analytics | Video metadata, retention heatmap, chapter markers, and threaded comments with derived engagement rate and view velocity |
| YouTube Transcript Scraper With View & Like Analytics | Video transcripts paired with view/like metadata and locally computed engagement analytics |
| Instagram Comments Scraper With Engagement Analytics | Instagram post/reel comments with engagement metrics |
| Facebook Comments Scraper | Comments scraped from Facebook posts |
| Facebook Group Comments & Replies Scraper | Comments and replies from Facebook Group posts |
| Reddit Comment Scraper (Sentiment & Lead Scoring) | Reddit comments with sentiment and lead-scoring fields |
How to integrate YouTube Comments Scraper With Reply Thread Expansion with your stack
YouTube Comments Scraper With Reply Thread Expansion works with any language or tool that can call the Apify API — the examples below use Apify's official client SDKs, the genuine way this Actor is invoked programmatically.
Python
from apify_client import ApifyClientimport csvclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")video_urls = ["https://www.youtube.com/watch?v=KrLj6nc516A","https://www.youtube.com/watch?v=dQw4w9WgXcQ",]run_input = {"videoUrls": video_urls,"maxTopLevelComments": 50,"fetchAllReplies": True,"maxRepliesPerComment": 100,"excludeKeywords": ["spam"],}run = client.actor("Scrapio/youtube-comments-scraper-with-reply-thread-expansion").call(run_input=run_input)rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())with open("youtube_comments.csv", "w", newline="", encoding="utf-8") as f:writer = csv.DictWriter(f, fieldnames=rows[0].keys())writer.writeheader()writer.writerows(rows)print(f"Saved {len(rows)} comment/reply rows to youtube_comments.csv")
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_API_TOKEN>' });const run = await client.actor('Scrapio/youtube-comments-scraper-with-reply-thread-expansion').call({videoUrls: ['https://www.youtube.com/watch?v=KrLj6nc516A'],maxTopLevelComments: 50,fetchAllReplies: true,maxRepliesPerComment: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Fetched ${items.length} rows`);console.log(items[0]);
Async and scheduled pipelines
The Actor is invoked as a standard Apify Actor run — there is no separate webhook server inside the Actor itself. For fire-and-forget large jobs, start the run via client.actor(...).start() instead of .call(), poll the run status or dataset via the Apify API, or configure an Apify webhook on the run-succeeded event to notify your own endpoint. Recurring jobs use the Apify platform's Schedule feature to trigger runs on a cron-style interval against a fixed videoUrls list.
🎯 Who Needs YouTube Comments Scraper With Reply Thread Expansion? (Use Cases & Industries)
🏢 Brand, community, and moderation teams
A community manager pulls every reply under a flagged top-level comment (replyToCid chains back to the parent cid) to see whether a complaint escalated in the replies before deciding whether to respond publicly or pin a clarifying comment.
📊 AI/ML teams building RAG and training data
Teams indexing comment text alongside videoId and title into a vector store get a sourced, attributable feed of audience reaction for retrieval-augmented answers about "what viewers think of video X," without re-scraping HTML for each new video.
📱 Competitive intelligence and marketing teams
Marketing teams run the Actor against competitor product-launch videos with includeKeywords set to their own or a competitor's product name, tracking voteCount on those specific mentions over multiple runs to see which claims are actually landing with viewers.
🔬 Researchers
Academic and social researchers use the full reply-thread expansion to study complete public conversation structures — not the truncated top-level sample most comment scrapers return — while only ever touching publicly accessible comments.
🎥 Product and SaaS builders
Builders of sentiment dashboards and moderation-assist tools use the Actor's stable 20-field JSON as the ingest layer behind their own scoring or classification models, without writing YouTube-specific HTML parsing themselves.
Is it legal to scrape YouTube?
Scraping publicly accessible web pages is generally lawful in the United States — courts have repeatedly held that accessing data a website makes available to any visitor without a login does not violate the Computer Fraud and Abuse Act (see hiQ Labs, Inc. v. LinkedIn Corp., 9th Cir. 2019, reaffirmed on remand 2022). Separately, scraping in a way that breaches a platform's Terms of Service can expose the scraper to a civil contract claim from that platform — a different and independent question from criminal liability. Because this Actor returns commenter handles, avatar images, and comment text tied to identifiable YouTube accounts, that output is personal data under frameworks like GDPR and CCPA: storing, processing, or publishing it carries data-protection obligations that sit with whoever runs the Actor, not with the Actor itself. YouTube Comments Scraper With Reply Thread Expansion 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 Comments Scraper With Reply Thread Expansion work without a YouTube account?
Yes. The Actor fetches public video pages and the same /youtubei/v1/next endpoint an anonymous browser uses — no YouTube login or API key is required. It only returns data visible to a logged-out visitor, so private, unlisted-without-link, or age-restricted videos are out of scope.
How does it handle YouTube's anti-scraping measures?
On a 403/429 response, the Actor automatically escalates from no proxy to a datacenter proxy, then to a residential proxy, retrying up to MAX_RETRIES = 3 times with a backoff delay between attempts. Requests also rotate a realistic Chrome user-agent string matched to the detected client version.
Can I run it at scale without getting blocked?
Multiple videos in videoUrls are processed sequentially within one run, with proxy escalation handling individual blocks as they occur. No fixed rate limit or concurrency cap is published for this Actor; for very large batches, running multiple parallel Actor runs (each with its own videoUrls subset) via the Apify API scales better than one very large run.
How fresh is the data it returns?
Fully live — every run fetches the video page and comment continuations directly from YouTube at request time. Nothing is cached or served from a prior run; re-running against the same video returns whatever comments and replies exist at that moment.
Does scraping YouTube comments violate YouTube's Terms of Service?
Scraping public pages does not, by itself, violate US anti-hacking law (see the hiQ v. LinkedIn citation above), but YouTube's own Terms of Service restrict automated access — breaching those terms is a potential civil contract issue between the scraper and YouTube, not a criminal one. Users are responsible for evaluating that risk for their own use case.
Which fields work best for AI training and RAG indexing?
comment is the primary high-information text field for both RAG retrieval and training corpora. For RAG, pair it with videoId, title, and publishedTimeText so retrieved passages are attributable to a specific video and time. For training data, type and isChild give a consistent, non-null way to separate top-level comments from replies across the entire dataset without per-row branching — every field returns as a typed primitive (string, integer, or boolean), requiring no additional normalization.
Does this Actor return personal data, and who is responsible for handling it?
Yes — author (handle), avatar (profile image URL), and comment text tied to an identifiable account are personal data under regimes like GDPR and CCPA. The Actor only surfaces what YouTube already displays publicly; the lawful basis for storing, processing, or further using that data rests with whoever operates the Actor, not with the Actor itself.
Does it work with Claude, ChatGPT, and other AI agent tools?
There is no dedicated MCP server for this Actor. It is callable as a standard Apify Actor run through the Apify API by any agent framework capable of making an HTTP request — every response is typed JSON, so no HTML parsing is needed before passing results into an LLM's context window.
What happens if I set maxRepliesPerComment to 0?
0 means no cap on replies kept per parent comment — the Actor keeps following that comment's reply-continuation token until YouTube stops returning new replies or a 40-page-per-comment safety valve is reached (MAX_REPLY_PAGES_PER_PARENT = 40), guaranteeing the run still terminates on an exceptionally large thread.
Will my existing base-actor input JSON still work with this Actor?
Yes. startUrls, maxComments, sortOrder, and the hidden language/region keys from the base YouTube Comments Scraper are all still accepted as fallbacks — the new field names (videoUrls, maxTopLevelComments, commentSortOrder, commentLanguage, commentRegion) take priority if both are present, but old input JSON does not need to be rewritten.
ℹ️ Disclaimer
YouTube Comments Scraper With Reply Thread Expansion 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.