YouTube Video & Channel Scraper — Stats, Metadata, Views avatar

YouTube Video & Channel Scraper — Stats, Metadata, Views

Pricing

from $15.00 / 1,000 video scrapeds

Go to Apify Store
YouTube Video & Channel Scraper — Stats, Metadata, Views

YouTube Video & Channel Scraper — Stats, Metadata, Views

Scrape YouTube video metadata and channel data by URL, ID or @handle — view counts, subscriber counts, video lists, duration, category, keywords. Filter by views, duration, date or title before paying. A no-API-key alternative to the YouTube Data API. No login. Charged only for results returned.

Pricing

from $15.00 / 1,000 video scrapeds

Rating

0.0

(0)

Developer

Nicholas Cheng

Nicholas Cheng

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

1

Monthly active users

6 days ago

Last modified

Share

YouTube Video & Channel Scraper

Give it a video link or a channel handle, get structured JSON back. No API key, no OAuth, no login, no cookies, no quota to apply for. Point it at dQw4w9WgXcQ, https://www.youtube.com/watch?v=…, @veritasium, or a UC… channel ID.

You are charged only for results that actually came back. A private, deleted, or region-blocked video produces an explanatory row and costs nothing.

InputVideo URLs / IDs (watch, Shorts, youtu.be, embed) and channel URLs / @handles / UC… IDs
OutputVideo metadata + channel profiles, as separate rows
Price$0.015 per video · $0.005 per channel — the same on every Apify plan
API keyNot needed. This does not use the YouTube Data API, so it does not consume your quota
TranscriptsOptional — tick includeSubtitles. Included in the per-video price. See Transcripts

What you get

Videos

{
"itemType": "video",
"videoId": "aircAruvnKk",
"url": "https://www.youtube.com/watch?v=aircAruvnKk",
"title": "But what is a neural network? | Deep learning chapter 1",
"description": "Full text of the video description, not truncated.",
"durationSeconds": 1120,
"viewCount": 23951183,
"likesLabel": "like this video along with 512,000 other people",
"publishedAt": "2017-10-05T00:00:00-07:00",
"channelId": "UCYO_jab_esuFRV4b17AJtAw",
"channelName": "3Blue1Brown",
"channelUrl": "https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw",
"channelSubscribersLabel": "7.4M subscribers",
"keywords": ["neural networks", "deep learning", "machine learning"],
"category": "Education",
"isLive": false,
"thumbnail": "https://i.ytimg.com/vi/aircAruvnKk/maxresdefault.jpg",
"availableCaptions": [
{ "language": "en", "name": "English", "isAutoGenerated": false },
{ "language": "es", "name": "Spanish", "isAutoGenerated": false }
]
}

viewCount and durationSeconds are real numbers, not display strings — you can sort and filter on them without parsing "1.2M" first. likesLabel is a string on purpose: YouTube no longer exposes an exact like count to logged-out clients, and inventing a number from a rounded label would be making data up.

availableCaptions lists which caption tracks a video has, in which languages, and whether they are human-written or auto-generated. The text itself comes with includeSubtitles — see below.

Transcripts (optional)

Tick includeSubtitles and every video row also carries what is said in the video. Real output (the transcript fields of the row for jNQXAC9IVRw):

{
"transcriptLanguage": "en",
"transcriptType": "manual",
"transcript": "All right, so here we are, in front of the elephants the cool thing about these guys is that they have really... really really long trunks and that's cool (baaaaaaaaaaahhh!!) and that's pretty much all there is to say",
"subtitles": [
{
"language": "en",
"type": "manual",
"name": "English",
"text": "All right, so here we are, in front of the elephants the cool thing about these guys is that they have really... really really long trunks and that's cool (baaaaaaaaaaahhh!!) and that's pretty much all there is to say",
"segments": [
{ "start": 1.2, "end": 3.36, "text": "All right, so here we are, in front of the elephants" },
{ "start": 5.318, "end": 7.974, "text": "the cool thing about these guys is that they have really..." },
{ "start": 7.974, "end": 12.616, "text": "really really long trunks" },
{ "start": 12.616, "end": 14.367, "text": "and that's cool" },
{ "start": 14.421, "end": 15.733, "text": "(baaaaaaaaaaahhh!!)" },
{ "start": 16.881, "end": 18.881, "text": "and that's pretty much all there is to say" }
]
}
],
"subtitlesNote": null
}
  • transcript — the full text of one caption track in the language that is spoken in the video: the human-written captions when the video has them in that language, otherwise YouTube's auto-generated ones. transcriptLanguage is YouTube's language code; transcriptType is manual or auto-generated.
  • subtitles — that same track with timed segments ({ start, end, text }, in seconds), for anything that needs to point back to a moment in the video.
  • Auto-generated captions arrive from YouTube as "roll-up" cues that repeat each line two or three times; they are de-duplicated, so the transcript reads as one pass of the speech.
  • When there is nothing to return, transcript is null and subtitlesNote says why — most often the video simply has no captions on YouTube.

Transcripts are part of the video row and cost nothing extra — see Pricing.

Channels

Each channel you pass returns one profile row, plus the videos you asked for:

{
"itemType": "channel",
"channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
"channelName": "NASA",
"handle": "@NASA",
"subscribersLabel": "15.1M subscribers",
"videoCountLabel": "6.1K videos",
"description": "NASA's mission is to explore the unknown in air and space…",
"videosOnPage": 30
}

Channel rows also carry the contact details the channel owner published in the description, already split into columns: emails, phones, externalLinks, linkInBio, otherSocials — for example @mkbhd returns "emails": ["business@mkbhd.com"]. Nothing is unlocked: the "View email address" button on YouTube's About tab sits behind a CAPTCHA, and this Actor does not touch it. No extra charge.


Input

{
"videoUrls": ["https://www.youtube.com/watch?v=aircAruvnKk", "dQw4w9WgXcQ"],
"channelUrls": ["@veritasium", "https://www.youtube.com/@NASA"],
"maxVideosPerChannel": 10,
"includeChannelProfile": true,
"maxItems": 0,
"minViews": 100000,
"minDurationSeconds": 60,
"publishedAfter": "2026-01-01"
}
OptionDefaultNotes
videoUrls—Watch, Shorts, youtu.be, embed, live links, or bare 11-character IDs
channelUrls—@handle, /channel/UC… URL, /c/…, /user/…, or a bare UC… ID
maxVideosPerChannel10Per channel, counting only videos that pass the filters. 0 returns channel profiles only
includeSubtitlesfalseAlso return each video's transcript with timestamps. No extra charge. See Transcripts
includeChannelProfiletrueOne profile row per channel
maxItems0Hard cap on rows for the whole run — bounds your spend
minViews0Skip videos with fewer views
minDurationSeconds / maxDurationSeconds0Skip videos outside this length window — e.g. minDurationSeconds: 61 drops Shorts
publishedAfter—ISO date; videos published before it are skipped
titleContains—Keep only titles containing at least one of these, case-insensitive

maxVideosPerChannel applies per channel, in one run. Monitoring forty channels and taking the five newest videos from each is a single run, not forty.

Filtering by views, duration, date, title

The filters exist so you can pay for the videos you want and none of the others. Two things make that literally true rather than a figure of speech:

  1. Videos that fail a filter are not delivered and not charged. They do not appear in the dataset; the run summary counts them under filteredOut.
  2. Channel videos are screened before their page is fetched. A channel listing already shows each video's rounded view count, length, and relative age. Anything that cannot pass on those — "12K views" against minViews: 100000, a 0:42 clip against minDurationSeconds: 60 — is dropped without loading its page, which is the expensive part. The screen is deliberately conservative: a rounded label is read at its upper bound, a relative date at its most recent possible value, and anything unparsable is let through. The exact fields are checked again once the page is loaded, so nothing that should have been excluded slips in.

Videos you pass directly in videoUrls are fetched and then checked on their real fields.

What the filters cannot do: a channel page lists roughly its 30 most recent uploads, and this Actor does not page further back. If fewer than maxVideosPerChannel of those pass your filters, you get fewer, and the log says so. publishedAfter narrows which of the listed videos you get; it does not reach older ones.


Pricing

Pay-per-event. You pay for what came back, nothing else.

EventPriceWhat it covers
video-scraped$0.015One video with full metadata — plus its transcript if you asked for it.
channel-resolved$0.005One channel profile plus its recent video list. Charged once per channel.

Two events because the work is shaped that way: resolving a channel is cheap, loading a video page is not. Splitting them means a channel-listing job is not priced as if it were a video job.

What you are not charged for

Every item below is checkable against a run log:

What happens here
Unavailable videosPrivate, deleted, region-blocked, or mistyped IDs produce one row marked chargedForThis: false. Nothing is billed.
Empty or placeholder rowsIf the video data did not come back, no row is written. There are no filler rows in your dataset.
Filtered-out videosA video that fails minViews, the duration window, publishedAfter, or titleContains is not delivered and not billed. Channel videos that fail on the listing are never even fetched.
The free planSame code path, same fields, same limits. No demo mode, no 10-row cap, no nulls in place of data.
Plan-tiered pricing$0.015 per video on every Apify plan — Free, Bronze, Silver, Gold, Platinum, Diamond. Check the Pricing tab: all six columns are identical.

That last row is worth checking on any Actor you compare, including this one. The Pricing tab shows the per-plan breakdown, and the price a listing advertises in its title is not always the price a free-plan run pays.


What this Actor cannot do

Being straight about this up front so you do not buy the wrong tool:

  • No speech recognition of our own. Transcripts are YouTube's own captions. A video with no captions on YouTube gets an empty transcript and a note; we do not download the audio and transcribe it.
  • A correction. An earlier version of this page said transcripts were impossible because YouTube's caption links come back empty. That was true of the links YouTube gives the web player, which require a proof-of-origin token — and we had only tested those. YouTube's mobile apps get caption links that need no such token, and that is what this Actor uses.
  • No comments.
  • No search. This works from links and handles, not keywords. titleContains filters the videos a channel lists; it does not search YouTube.
  • No deep channel history. A channel page lists about 30 recent uploads and the Actor does not page further, so filters select from those, not from the whole back catalogue.
  • No exact like counts. YouTube stopped exposing them to logged-out clients. You get the rounded accessibility label instead, verbatim.
  • No private, members-only, or age-gated videos. Those require an account, and this Actor never signs in to anything.

How it stays working

Video pages are fetched through rotating residential connections because YouTube shows a bot check to datacenter addresses — we measured 1 usable response in 10 without one, and 9 in 10 with. Channel pages need no such thing and are fetched directly, so a channel-listing job does not pay for bandwidth it does not need.

The Actor also stops downloading each video page as soon as it has the two embedded JSON blocks it needs, rather than pulling the full 1.3 MB. That is roughly half the bytes, and it is why the per-video price can stay where it is.

Transcripts take one more request per video: the caption list is fetched the way YouTube's mobile apps fetch it (trying the iOS, Android VR and Android app clients in turn, each from a fresh residential address), and the caption file itself is downloaded directly. Measured over three rounds of fifteen videos — news, lectures, music, German, Korean and Arabic speech among them — the caption list came back for 14, 15 and 15 of 15 on a single pass, and all 170 caption downloads returned text. When YouTube shows a bot check, the Actor moves to the next client and a new address, up to six tries, before reporting the video's transcript as unavailable.


Integrating

Every run writes to a standard Apify dataset, so the usual routes all work: the REST API, the JavaScript and Python clients, scheduled runs, webhooks, and the MCP server for agent use. Two dataset views are provided — Videos & channels for everything, Channels only for the profile rows on their own.