YouTube Scraper - Videos, Channels & Transcripts
Pricing
from $1.50 / 1,000 results
YouTube Scraper - Videos, Channels & Transcripts
Search YouTube videos, list channel videos, and collect public channel details, comments, replies, and available transcripts. Pay per delivered row plus a start fee.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
16
Total users
2
Monthly active users
a day ago
Last modified
Categories
Security
Limited permissionsShare
YouTube Scraper
Collect YouTube videos, channel information, comments, and available transcripts as rows you can export for research.
- Discover videos by keyword, channel, direct video link, or popular topic.
- Compare titles, publishing dates, engagement, and channel statistics.
- Add captions and metadata to shortlisted videos.
- Export comments and replies as separate rows.
- Pay $1.50 per 1,000 delivered rows plus a small start fee.
What does YouTube Scraper do?
YouTube Scraper collects public data from youtube.com for content research, channel monitoring, and transcript analysis. You can combine several inputs in one run. Each row represents one video, channel, or comment; replies are comment rows too.
- Search: use
searchQuerieswith optional date, duration, and result-type filters. - Channels: use
channelUrlsto list videos, shorts, streams, or all three tabs. - Known videos: use
videoUrlsfor specific videos, optionally adding details or captions. - Popular topics: enable
includeTrendingfor topic-based discovery in the market selected bygl. - Extra rows:
includeComments,includeRelated, andincludeChannelAboutare off by default. Every extra row costs the same as a video row and uses the originating input's allowance. Replies are enabled when comments are enabled, unless you turn offincludeCommentReplies.
Transcripts are fields on video rows, not extra billed rows. Use discovery first, review the titles, then request details or transcripts for a shortlist.
What data can you extract from YouTube?
Every row has rowType and a stable id. The same rowType and id pair is deduplicated. Optional fields depend on what YouTube exposes and which options you enable.
Video rows
| Field | Description | Example |
|---|---|---|
videoId | YouTube video identifier. | XVv6mJpFOb0 |
title | Video title. | Example tutorial |
url | Video watch URL. | https://www.youtube.com/watch?v=XVv6mJpFOb0 |
channelName | Public channel name. | Example Channel |
viewCount | Parsed count; zero can mean unavailable. | 12500 |
durationSeconds | Video length in seconds. | 480 |
publishedAt | Publishing date or estimated date. | 2026-09-12 |
publishedAtApproximate | Whether the date came from relative text. | true |
description | Search snippet or fuller description. | Example lesson description |
chapters | Chapter titles and starting times, when available. | [{"title":"Intro","startMs":0}] |
transcript | Caption segments; at most 50 are retained. | [{"text":"Example caption","start":0,"duration":2}] |
transcriptText | Joined caption text, subject to size limits. | Example caption |
transcriptLanguage | Language actually returned. | en |
enrichmentLevel | Enrichment applied to the video. | transcript |
Channel rows
| Field | Description | Example |
|---|---|---|
channelId | Channel identifier. | UCXXXXXXXXXXXXXXXXXXXXXX |
channelName | Public channel name. | Example Channel |
channelUrl | Public channel link. | https://www.youtube.com/@Example |
handle | Channel handle, when available. | @Example |
subscriberCount | Parsed subscriber count. | 15000 |
totalViews | Channel lifetime views, when shown. | 800000 |
videoCount | Channel video count, when shown. | 120 |
links | Public links listed by the channel. | [{"title":"Website","url":"https://example.com"}] |
Comment and reply rows
| Field | Description | Example |
|---|---|---|
commentId | Comment or reply identifier. | example-comment-id |
videoId | Parent video identifier. | XVv6mJpFOb0 |
authorName | Public author display name. | Jane Doe |
text | Comment text. | Example comment text |
isReply | Whether this row is a reply. | true |
parentCommentId | Parent comment for a reply. | example-parent-id |
rootCommentId | Top-level comment in the thread. | example-parent-id |
likeCount | Likes when exposed. | 12 |
How to scrape YouTube
- Open YouTube Scraper in Apify Console.
- Fill one target field, such as
searchQueries. - Set
maxResultsto3for a small first run. - Click Start and wait for completion.
- Open the dataset and download the rows or read them through the API.
With no target filled, the Actor reads the sample channel https://www.youtube.com/@freecodecamp (videos tab), limited to three rows. This example uses normal pricing, including the start fee. Filling a target selects the matching collection path automatically; no separate mode selection is needed. Mixed inputs are supported.
Search by keyword
Enter topics in searchQueries. Use gl for the market and hl for the interface language. For example, gl: "JP" selects Japan; when hl is omitted, the Actor selects a language for the market. These settings are separate from caption language.
List channel videos
Enter public channel links, channel IDs, or handles in channelUrls. Select channelTab: videos, shorts, streams, or all. All tabs share one allowance per channel. Enable includeChannelAbout to add a channel row before its videos.
Collect known videos and transcripts
Enter watch, shorts, live, embed, or youtu.be links, or 11-character IDs, in videoUrls. Enable scrapeDetails for richer metadata and includeTranscript for captions. Caption extraction can fall back to another available language; check the returned transcriptLanguage.
Discover popular topics
Set includeTrending to true and choose gl. Results come from popular topic hubs, not a complete ranked list of everything trending. Rows may include trendingTopic. Trending counts as one input.
What to fill in
| Field | What to enter | Default |
|---|---|---|
searchQueries | Keywords; up to 50 entries. | Empty; sample prefilled |
channelUrls | Channel links, IDs, or handles; up to 50. | Empty |
videoUrls | Video links or IDs; up to 500. | Empty |
maxResults | Rows per distinct input, from 1 to 1,000. | 70; form prefill 3 |
includeTrending | Add popular-topic discovery. | Off |
trendingMaxResults | Smaller trending candidate cap, up to 200. | Smaller of maxResults and 200 |
gl | Two-letter country code, such as US or JP. | US |
hl | Interface language, such as en or ja. | Selected from gl |
uploadDate | any, hour, today, week, month, year. | any |
resultType | any, video, channel, playlist, movie, short. | any |
duration | any, short, medium, long. | any |
channelTab | videos, shorts, streams, all. | videos |
includeChannelAbout | Add a public channel-information row. | false |
scrapeDetails | Request richer video metadata. | false |
includeTranscript | Request available captions. | false |
transcriptLanguage | Preferred caption language. | en |
includeComments | Add comment rows. | false |
includeCommentReplies | Add replies when comments are enabled. | true |
maxComments | Top-level comment cap per video; 0 uses safety limits. | 0 |
maxRepliesPerComment | Reply cap per comment; 0 uses safety limits. | 0 |
commentSort | top or newest. | top |
includeRelated | Add related videos as separate rows. | false |
maxRelated | Related videos considered per source video. | 20 |
includeEngagement | Include available engagement counts with details. | true |
includeStructure | Include available chapters, topics, and hashtags with details. | true |
includePlaybackMeta | Include available playback metadata with details. | true |
includeFormats | Include available format information with playback metadata. | Follows includePlaybackMeta |
includeCardsEndscreen | Include cards and end-screen information with details. | true |
includeUpdatedMetadata | Refresh available video metrics. | false |
includeResolveHandle | Resolve channel identifiers; use includeChannelAbout for channel rows. | false |
includeGuide | Add category-navigation information to the run summary, not rows. | false |
concurrency | Concurrent video enrichment operations, 1–16. | 6 |
proxyCountry | Optional two-letter country override. | Selected market |
useProxyForSearch | Apply the country setting to search and channel results. | false |
Search example
{"searchQueries": ["ai workflow automation"],"maxResults": 3}
Channel example
{"channelUrls": ["https://www.youtube.com/@freecodecamp"],"channelTab": "videos","maxResults": 3}
Video and transcript example
{"videoUrls": ["https://www.youtube.com/watch?v=XVv6mJpFOb0"],"scrapeDetails": true,"includeTranscript": true,"transcriptLanguage": "en","maxResults": 1}
Popular-topic example
{"includeTrending": true,"gl": "US","maxResults": 3}
maxItems and limit are accepted aliases for maxResults. Target aliases include query and keywords for searchQueries, channels for channelUrls, and videoIds for videoUrls. Comma- or newline-separated target text is split into entries.
Close field-name misspellings can be corrected; other unknown fields are ignored with a note. Unsupported filter values are ignored with a warning. Every run writes its input interpretation to INPUT_REPORT in the default key-value store. Invalid target links stop collection with a message such as INVALID_INPUT: videoUrls — use a YouTube video link ... or the 11-character video ID, before any row is charged. The start fee still applies. uploadDate is a relative filter; the Actor does not automatically widen it.
Output example
Illustrative video row; values below are examples, not a captured result:
{"rowType": "video","id": "XVv6mJpFOb0","videoId": "XVv6mJpFOb0","title": "Example tutorial","url": "https://www.youtube.com/watch?v=XVv6mJpFOb0","channelName": "Example Channel","viewCount": 12500,"durationSeconds": 480,"publishedAt": "2026-09-12","description": "Example lesson description","gl": "US","hl": "en","source": "search","scrapedAt": "2026-10-24T00:00:00Z"}
Export the dataset as JSON, CSV, Excel, XML, RSS, or an HTML table. JSON preserves nested caption and chapter lists. RUN_SUMMARY records delivered counts and warnings; ERROR_SUMMARY provides failure details when written.
Why use this YouTube scraper?
- Research in stages. Discover first, then enrich a shortlist rather than requesting every optional field immediately.
- Several inputs together. Combine keywords, channels, and known videos in one run.
- Consistent billing. Each delivered row uses the same price, including comments and replies.
- Visible input handling. Inspect
INPUT_REPORTfor corrections and ignored fields. - No proxy setup. You do not need to set up proxies.
How much does it cost to scrape YouTube?
The Actor uses pay-per-event pricing: $0.005 per start event, plus the row price below. Platform usage is included in these prices.
| Apify plan | Price per row | Price per 1,000 rows |
|---|---|---|
| Free | $0.0015 | $1.50 |
| Starter | $0.0015 | $1.50 |
| Scale | $0.0015 | $1.50 |
| Business | $0.0015 | $1.50 |
Start billing is one event per GB of allocated memory, with a minimum of one. At the default 512 MB, one start costs $0.005. Video details and transcripts do not add a separate row charge; channel, comment, reply, and related-video rows each count separately.
maxResultsapplies to each distinct input, defaults to70, and accepts up to1,000. Larger collections are processed in parts.- All row types from one input share its allowance. A video can consume the only available row when
maxResultsis1, leaving no room for comments. - Free Apify plan runs are capped at 200 rows across all inputs.
- The run also stops at your Maximum cost per run (
maxTotalChargeUsdin the API). Fewer available results can mean fewer rows.
Example: three keywords delivering 50 rows each produce 150 rows. At 512 MB with one start, the cost is 150 × $0.0015 + $0.005 = $0.230 on the Free plan.
What happens when the run timeout is too short
Some runs take longer than the run timeout you chose, for example many keywords or channels with comments and transcripts turned on. In that case the run does not fail. It ends early with the status message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." and shows as ABORTED for a while. When the results are ready, the same run starts again by itself, reports "Resumed: delivering N rows.", writes the rows to the same dataset and finishes as SUCCEEDED. Rows already delivered are skipped, so no row is delivered or charged twice, and you do not need to start another run.
- This can happen at most 3 times per run. For larger jobs, choose a longer run timeout rather than a very short one. A manual abort or an unrelated failure is not the same as this automatic pause.
- The synchronous API endpoints (
run-sync,run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For larger jobs, start the run asynchronously and read the dataset after the run reaches SUCCEEDED, or use a webhook on theACTOR.RUN.SUCCEEDEDevent.
Use with AI agents and the API
Apify MCP server (Claude, ChatGPT, Cursor, VS Code)
Add the Actor to an MCP client that supports remote servers:
https://mcp.apify.com?tools=lentic_clockss/youtube-research-scraper
Sign in with Apify when prompted through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns run and dataset IDs; read rows with get-dataset-items. Clients without remote support can use npx @apify/actors-mcp-server --tools lentic_clockss/youtube-research-scraper with APIFY_TOKEN set.
Example prompt: "Search YouTube for ai workflow automation and return three video rows with titles, links, and channel names."
Apify API
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/youtube-research-scraper").call(run_input={"searchQueries": ["ai workflow automation"], "maxResults": 3})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/youtube-research-scraper').call({searchQueries: ['ai workflow automation'], maxResults: 3});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Over HTTP, send the input JSON to POST https://api.apify.com/v2/acts/lentic_clockss~youtube-research-scraper/runs with your token in the Authorization: Bearer header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.
Integrations
Use the Actor's Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable, or your own webhook. Use Apify Schedules for recurring collection.
FAQ
Is it legal to scrape YouTube?
This Actor collects public data. You are responsible for complying with YouTube's terms and applicable data-protection law. Processing personal data, including comment author information, requires a lawful basis.
Why did my run end as ABORTED?
The run was stopped before normal completion. Check its status message and log for the reason; do not assume it will resume automatically. Inspect the dataset before starting again. Delivery of unfinished collection is not guaranteed.
How many results can I get?
maxResults allows 1–1,000 rows per input. Available data, shared allowances for extra rows, duplicate removal, the Free plan cap, and your cost limit can reduce the total.
Why are some fields empty?
YouTube may omit captions, counts, dates, or playback information. Optional enrichment can also fail while leaving a video row available. Missing values can be absent, empty, null, or zero; zero does not always prove a measured count of zero.
Can I get every comment and reply?
Not necessarily. maxComments: 0 and maxRepliesPerComment: 0 use safety limits of 20,000 top-level comments and 2,000 replies per comment, but the input's row allowance takes precedence. Disabled comments or unavailable threads cannot be collected.
Are transcripts always complete?
No. Captions may be unavailable. The segment list retains at most 50 entries; transcriptSegmentCount records the count before that limit. transcriptText is capped at 100,000 characters and may be shortened further by the row-size limit.
Do I need a YouTube Data API key?
No YouTube Data API key is required. Programmatic access through Apify uses your Apify token.
Limitations
- Search filters do not guarantee matching rows. The
playlistfilter is not a playlist export; delivered row types remain video, channel, and comment. - Topic discovery is not an exhaustive popularity ranking, and results vary by market and language.
- Private, deleted, restricted, or unavailable content may yield limited data or no rows. An entirely empty collection is reported as a failure.
- Selected attribute lists retain at most 50 entries. Size reduction may remove fields; inspect
rowTruncatedFieldsandrowOversizeReduced. - Derived publishing dates are marked by
publishedAtApproximate. Do not treat them as exact timestamps.
Related scrapers
More social media and video scrapers from the same publisher:
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Found a problem or need another field? Open an issue in the Issues tab of this Actor's page and include the run ID and the input you used.