YouTube Shorts Scraper avatar

YouTube Shorts Scraper

Pricing

from $2.90 / 1,000 shorts

Go to Apify Store
YouTube Shorts Scraper

YouTube Shorts Scraper

Scrape YouTube Shorts from channels, search queries, and direct URLs. Extract video metadata, engagement metrics, subtitles, translations, and detailed channel information.

Pricing

from $2.90 / 1,000 shorts

Rating

0.0

(0)

Developer

Upadhyay Labs

Upadhyay Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 hours ago

Last modified

Categories

Security

Limited permissions

Share

YouTube Shorts Scraper

Extract structured data from YouTube Shorts at scale — titles, view counts, likes, durations, hashtags, upload dates, captions, and full channel statistics — from any channel, search query, or direct Shorts URL. No browser required, no YouTube API key, no daily quota.

Try it instantly: paste mkbhd into the Channels field and click Start.


What does YouTube Shorts Scraper do?

YouTube Shorts Scraper collects metadata from public YouTube Shorts without a browser or a YouTube Data API key. It reads the same public data YouTube's own web pages render and paginates through channel Shorts tabs and search results — the same mechanism the "load more" button uses on the site.

Each output row contains:

  • Video metadata: title, URL, thumbnail, view count, likes, duration, upload date, description, hashtags, links, comment count, age-restriction status, paid-promotion flag, members-only flag, collaborators
  • Subtitles / captions: full SRT text for configured languages (auto-generated or user-submitted tracks)
  • Channel details: name, handle, subscriber count, verification badge, avatar, banner, description, join date, total views and videos, country, social links
  • Provenance: which input triggered this result, what URL was actually scraped, position in the listing, timestamp

Supported input sources:

SourceExample
Channel handlemkbhd, @NASA
Channel IDUCBcRF18a7Qf58cCRy5xuWwQ
Channel URLhttps://www.youtube.com/@mkbhd
Search query"satisfying ASMR"
Direct Short URLhttps://www.youtube.com/shorts/VIDEO_ID

Why use YouTube Shorts Scraper?

Building this on the Apify platform instead of a custom script gets you:

  • No YouTube Data API key or quota — the official API caps Shorts-relevant metadata and burns daily quota fast; this Actor reads the same public data YouTube's own web client renders, with no key and no 10,000-unit/day ceiling.
  • Lightweight and fast — no headless browser required, so runs finish 5–10× faster and use a fraction of the memory browser-based scrapers need for the same volume.
  • Built-in proxy rotation & session management — residential Apify Proxy integration and automatic session retirement on blocks, so you don't hand-roll IP rotation.
  • Pay only for results — Pay-Per-Event pricing charges per Short actually delivered, not per minute of compute.
  • Scheduling, webhooks, and API access — run on a cron schedule, trigger a webhook on completion, or call it from your own code via the Apify API or JS/Python clients.
  • Structured, typed output — every field has a documented type and a defined null meaning (never a guess), so downstream pipelines don't have to special-case missing data.

Use cases

  • Creator analytics — track posting frequency, engagement trends, and format evolution across any creator's Shorts library
  • Market research — benchmark your channel's like-to-view ratio and comment rate against competitors in the same niche
  • Influencer discovery — find active Shorts creators by topic, then filter by subscriber count and engagement rate
  • Content monitoring — watch a brand's or competitor's Shorts feed for new uploads, hashtags, or paid promotions
  • Caption and transcription pipelines — pull auto-generated or user-submitted SRT captions at scale for translation, summarization, or keyword extraction
  • SEO and hashtag research — identify which hashtags appear most on high-performing Shorts in a niche
  • Academic and social-media research — build datasets of short-form video engagement across channels or topics

How to scrape YouTube Shorts

1. Run on the Apify platform (no setup needed)

  1. Open the Actor on Apify Store and click Try for free.
  2. In the Input tab, add at least one Channel, Search query, or Direct URL.
  3. Adjust limits and enrichment options (see Input below).
  4. Click Start and wait for the run to finish.
  5. Download results from the Dataset tab in JSON, CSV, or Excel.

2. Run via the Apify API

Start a run and download results programmatically:

# Start a run
curl -X POST \
"https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channels": ["mkbhd"],
"maxResultsShorts": 50,
"extendedVideoDetails": true,
"extendedChannelDetails": true
}'

See the Apify API docs for full run management, webhooks, and dataset export endpoints.

3. Run via Apify JavaScript or Python client

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('YOUR_ACTOR_ID').call({
channels: ['mkbhd', 'nasa'],
maxResultsShorts: 100,
extendedVideoDetails: true,
extendedChannelDetails: true,
subtitleLanguages: ['en'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("YOUR_ACTOR_ID").call(run_input={
"channels": ["mkbhd", "nasa"],
"maxResultsShorts": 100,
"extendedVideoDetails": True,
"extendedChannelDetails": True,
"subtitleLanguages": ["en"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

How much will it cost to scrape YouTube Shorts?

This Actor uses Pay-Per-Event (PPE) pricing — you pay a flat, predictable fee for each Short actually written to the dataset, never for platform compute time, proxy bandwidth, or failed/retried requests.

EventCharged?
Short successfully scraped and saved✅ Yes — one event per Short
Error / placeholder row (no Shorts found, unavailable video, empty search)❌ No

Cost control: set maxItems or maxResultsShorts to cap output. The run also stops automatically once your configured budget limit (ACTOR_MAX_TOTAL_CHARGE_USD) is reached — you are never billed beyond what you approved.

See the Pricing tab on this Actor's Store page for the current per-event rate.


Input

At least one of channels, searchQueries, or startUrls is required. All other fields are optional.

Sources

FieldTypeDefaultDescription
channelsstring[]—Channel handles, @handles, channel IDs, or channel/Shorts URLs. Examples: "mkbhd", "@NASA", "UCBcRF18a7Qf58cCRy5xuWwQ", "https://www.youtube.com/@mkbhd"
searchQueriesstring[][]Plain-text search terms. Results come from YouTube's Shorts search tab.
startUrlsRequestSource[][]Direct https://www.youtube.com/shorts/VIDEO_ID links scraped individually, bypassing channel discovery.

Accepted channel formats

InputResolves to
"nasa" / "@NASA"/@NASA/shorts
"UCBcRF18a7Qf58cCRy5xuWwQ"/channel/UCBcRF18a7Qf58cCRy5xuWwQ/shorts
"https://www.youtube.com/@NASA/videos"/@NASA/shorts (tab switched automatically)
"https://www.youtube.com/c/nasa"/c/nasa/shorts

Duplicate inputs (e.g. "nasa" and "@NASA") are automatically deduplicated by resolved URL.

Limits & filtering

FieldTypeDefaultDescription
maxResultsShortsinteger25Maximum Shorts to collect per channel or search query. Range: 1–20,000.
maxItemsinteger0Global cap across the entire run. 0 = unlimited (bounded only by maxResultsShorts per source).
oldestPostDatestring—Stop paginating a source once Shorts older than this date are encountered. Accepts ISO dates ("2024-01-01") or relative values ("7 days", "2 days ago"). When set, sortChannelShortsBy is automatically forced to NEWEST.
sortChannelShortsBystring"NEWEST"Order for channel Shorts pages: NEWEST (most recent first), POPULAR (most viewed first), OLDEST (oldest first). Ignored for search queries.

Data enrichment

FieldTypeDefaultDescription
extendedChannelDetailsbooleantrueFetches the channel About page for description, join date, location, total views, total videos, avatar, and banner. One extra request per unique channel.
extendedVideoDetailsbooleantrueVisits each Short's watch page for exact like count, comment count, exact upload date, description, subtitle tracks, collaborators, and paid-promotion flag. ~2× slower but significantly richer data.
subtitleLanguagesstring[]["en"]BCP-47 language codes for which to download and populate full SRT caption text. Other tracks appear in output with srt: null (no extra request made). Set [] to skip all SRT downloads. Only applies when extendedVideoDetails is true.
translationLanguagestring""BCP-47 code (e.g. "es", "fr"). When set, re-fetches the watch page with ?hl=<lang> to get a localized title and description. translatedTitle and translatedText are null when no genuine translation exists. One extra request per video. Only applies when extendedVideoDetails is true.

Performance & proxy

FieldTypeDefaultDescription
proxyConfigurationobjectApify RESIDENTIALProxy settings. Residential proxies are strongly recommended — YouTube throttles datacenter IPs quickly.
maxRequestRetriesinteger6Maximum retries per failed request before recording an error row. Range: 0–20.
maxConcurrencyinteger15Parallel requests. Higher = faster, but YouTube throttles aggressive concurrency even through residential proxies. Avoid exceeding ~20 without also widening your proxy pool.

Example input — MKBHD's latest 50 Shorts with English captions

{
"channels": ["mkbhd"],
"maxResultsShorts": 50,
"sortChannelShortsBy": "NEWEST",
"extendedChannelDetails": true,
"extendedVideoDetails": true,
"subtitleLanguages": ["en"],
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Output

One dataset row per Short. Below is a real sample record from MKBHD's channel (mkbhd), with extendedVideoDetails: true and extendedChannelDetails: true:

{
"title": "This can SEE Sound!",
"type": "shorts",
"id": "ai1gIWacf0I",
"url": "https://www.youtube.com/shorts/ai1gIWacf0I",
"thumbnailUrl": "https://i.ytimg.com/vi/ai1gIWacf0I/maxresdefault.jpg",
"viewCount": 2213234,
"date": "2026-10-27T20:14:55.000Z",
"likes": 63749,
"durationSeconds": 90,
"duration": "00:01:30",
"likesToViewsRatio": 0.0288,
"commentsCount": 1294,
"commentsTurnedOff": false,
"text": "This is an acoustic imaging camera",
"descriptionLinks": [],
"hashtags": [],
"subtitles": [
{
"language": "English (auto-generated)",
"languageCode": "en",
"type": "asr",
"url": "https://www.youtube.com/api/timedtext?v=ai1gIWacf0I&...",
"isTranslatable": true,
"srt": null
}
],
"isMembersOnly": null,
"isAgeRestricted": false,
"isMonetized": null,
"isPaidContent": false,
"collaborators": [],
"location": null,
"translatedTitle": null,
"translatedText": null,
"aiVideoDescription": null,
"aiVideoSummary": null,
"transcriptionUrl": null,
"channelName": "Marques Brownlee",
"channelUrl": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ",
"channelId": "UCBJycsmduvYEL83R_U4JriQ",
"channelUsername": "mkbhd",
"numberOfSubscribers": 21400000,
"isChannelVerified": true,
"channelAvatarUrl": "https://yt3.googleusercontent.com/...",
"channelBannerUrl": "https://yt3.googleusercontent.com/...",
"channelDescription": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics...",
"channelJoinedDate": "Mar 21, 2008",
"channelTotalViews": 5847901236,
"channelTotalVideos": 1863,
"channelLocation": "United States",
"channelDescriptionLinks": [
{ "text": "Twitter", "url": "http://twitter.com/MKBHD" },
{ "text": "Instagram", "url": "http://instagram.com/MKBHD" }
],
"aboutChannelInfo": {
"channelName": "Marques Brownlee",
"channelUrl": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ",
"channelId": "UCBJycsmduvYEL83R_U4JriQ",
"channelUsername": "mkbhd",
"channelAvatarUrl": "https://yt3.googleusercontent.com/...",
"channelBannerUrl": "https://yt3.googleusercontent.com/...",
"channelDescription": "MKBHD: Quality Tech Videos | YouTuber | Geek...",
"channelJoinedDate": "Mar 21, 2008",
"channelTotalViews": 5847901236,
"channelTotalVideos": 1863,
"channelLocation": "United States",
"channelDescriptionLinks": [
{ "text": "Twitter", "url": "http://twitter.com/MKBHD" }
],
"numberOfSubscribers": 21400000
},
"inputChannelUrl": "https://www.youtube.com/@mkbhd",
"input": "mkbhd",
"fromYTUrl": "https://www.youtube.com/@mkbhd/shorts",
"fromChannelListPage": "shorts",
"order": 0,
"scrapedAt": "2026-10-30T16:26:56.338Z"
}

Output field reference

Video fields

FieldTypeNotes
titlestring|nullShort's title
translatedTitlestring|nullPopulated only when translationLanguage is set and YouTube has a genuine translation; null otherwise
translatedTextstring|nullSame gate as translatedTitle
typestringAlways "shorts"
idstringYouTube video ID
urlstringhttps://www.youtube.com/shorts/{id}
thumbnailUrlstring|nullmaxresdefault.jpg (1280×720) from YouTube CDN
viewCountinteger|nullTotal view count
datestring|nullISO 8601 UTC upload timestamp; requires extendedVideoDetails: true
likesinteger|nullLike count; requires extendedVideoDetails: true
durationSecondsinteger|nullDuration in whole seconds; requires extendedVideoDetails: true
durationstring|nullHH:MM:SS formatted duration; requires extendedVideoDetails: true
likesToViewsRationumber|nullround(likes / viewCount, 4); null when either value is missing or viewCount is 0
commentsCountinteger|nullFrom engagement panel or InnerTube /next; null when indeterminate (not the same as comments being disabled)
commentsTurnedOffboolean|nulltrue = explicitly disabled (confirmed signal), false = explicitly enabled (confirmed signal), null = could not determine
textstring|nullShort's description
descriptionLinksarrayLinks extracted from the description
hashtagsarray#tags extracted from title and description
subtitlesarray|nullCaption track objects; null when no tracks exist. Each object always includes an srt key.
isMembersOnlyboolean|nullnull when no members-only badge is detectable
isAgeRestrictedboolean|nulltrue = explicit age gate; false = isFamilySafe confirmed; null = no reliable signal (common on Shorts)
isMonetizednullAlways null — YouTube does not expose monetisation status in public data. Kept for schema compatibility.
isPaidContentbooleantrue only when YouTube's "Includes paid promotion" disclosure overlay is present; requires extendedVideoDetails: true
collaboratorsarray@-mentions extracted from the description
locationstring|nullThis video's location tag (not the channel's country); null for virtually all Shorts
aiVideoDescriptionnullNot implemented. Kept for schema compatibility.
aiVideoSummarynullNot implemented. Kept for schema compatibility.
transcriptionUrlnullNot implemented. Use subtitles[] for caption data.

Subtitle tracks — subtitles[]

Each object in the subtitles array:

FieldTypeNotes
languagestringHuman-readable language name (e.g. "English", "English (auto-generated)")
languageCodestringBCP-47 code (e.g. "en")
typestring"user_generated" or "asr" (auto-generated)
urlstringYouTube timedtext API URL — always present
isTranslatablebooleanWhether YouTube offers translation of this track
srtstring|nullFull SRT caption text when this track's language code matches subtitleLanguages; null otherwise (no extra request made)

SRT format: sequential 1-based index, HH:MM:SS,mmm --> HH:MM:SS,mmm timestamps, decoded text (no HTML entities).

Channel fields (top-level, always flat)

FieldTypeNotes
channelNamestring|nullChannel display name
channelUrlstring|nullCanonical /channel/UCxxxxxx URL
channelIdstring|nullUCxxxxxx identifier
channelUsernamestring|nullHandle without @
numberOfSubscribersinteger|nullSubscriber count
isChannelVerifiedboolean|nullVerified badge presence
channelAvatarUrlstring|nullChannel profile image URL
channelBannerUrlstring|nullChannel banner image URL
channelDescriptionstring|nullRequires extendedChannelDetails: true
channelJoinedDatestring|nullRequires extendedChannelDetails: true
channelTotalViewsinteger|nullRequires extendedChannelDetails: true
channelTotalVideosinteger|nullRequires extendedChannelDetails: true
channelLocationstring|nullChannel's declared country; requires extendedChannelDetails: true
channelDescriptionLinksarraySocial links from the channel About page; requires extendedChannelDetails: true
aboutChannelInfoobject|nullSelf-contained nested object with all channel fields above. null when extendedChannelDetails: false or fetch failed.

Provenance fields

FieldNotes
inputChannelUrlResolved @handle URL (e.g. https://www.youtube.com/@mkbhd). null for search sources.
inputThe raw value exactly as given in the input, unresolved.
fromYTUrlActual URL scraped to produce this record.
fromChannelListPage"shorts" for channel sources; null for search queries.
order0-based position in the source listing.
scrapedAtISO 8601 UTC timestamp of when this record was saved.

Error rows

When an input cannot be processed, the Actor pushes a structured error row to the dataset instead of crashing the run. Error rows are not charged as events.

{
"url": "https://www.youtube.com/@nonexistentchannel",
"input": "nonexistentchannel",
"error": "CHANNEL_DOES_NOT_EXIST",
"note": "Channel handle resolved to a 404.",
"scrapedAt": "2026-10-30T16:26:56.338Z"
}

Error codes

Error codeCause
CHANNEL_DOES_NOT_EXISTThe handle or URL does not resolve to a valid channel
CHANNEL_HAS_NO_SHORTSChannel exists and is accessible, but has no public Shorts
NOT_FOUNDHTTP 404 — page does not exist
PARSE_FAILEDPage loaded but ytInitialData JSON could not be read (YouTube layout change)
VIDEO_UNAVAILABLEVideo is deleted, private, or region-blocked
AGE_RESTRICTEDVideo requires a logged-in account to view
NO_RESULTSSearch query returned no Shorts
DATE_FILTER_TOO_STRICTShorts exist on the channel but none are newer than oldestPostDate
REQUEST_FAILEDAll retries exhausted (network error, persistent blocking)

Integrations

YouTube Shorts Scraper connects to the tools you already use — no extra code required.

Zapier

Trigger a Zapier Zap when a run finishes and automatically push Shorts data to Google Sheets, Airtable, Slack, or any of Zapier's 5,000+ apps. See Apify + Zapier integration.

Make (formerly Integromat)

Use the Apify Make module to start runs on a schedule and route results into your Make scenarios. See Apify + Make integration.

Google Sheets

Export any completed dataset directly to a Google Sheet from the Apify Console in one click, or automate it via the Apify Google Sheets integration.

Webhooks

Configure a webhook on the Actor run to POST the dataset URL to your own endpoint the moment the run succeeds. Go to Actor → Settings → Webhooks in the Apify Console.

Apify API

Every run, dataset, and key-value store is accessible via the Apify REST API v2. Paginate results, stream NDJSON, or poll run status programmatically.

MCP Server (AI agents)

This Actor is callable as a tool by any MCP-compatible AI agent (Claude, Cursor, etc.) via the Apify MCP Server. No additional setup — the Actor appears as a native tool once MCP is connected.

Scheduled runs

Set the Actor to run on a daily, weekly, or custom cron schedule from Actor → Settings → Schedules in the Apify Console. Combined with webhooks or Google Sheets export, this creates a fully automated YouTube Shorts monitoring pipeline.


Limitations

  • Subtitle SRT may be null even for a language listed in subtitleLanguages. YouTube's PoToken (proof-of-origin token) requirement can block automated caption retrieval on individual videos — this is a platform-wide restriction affecting all automated scrapers and cannot be reliably bypassed. The track's url field is always still returned regardless.
  • location is null for virtually all Shorts. It only populates for content derived from live broadcasts that carry a location tag.
  • isMonetized is always null. YouTube does not expose monetisation status in public InnerTube data.
  • commentsCount may be null even when comments are enabled. This happens when the engagement panel header omits the count — it is not the same as commentsTurnedOff: true.
  • commentsTurnedOff is three-state: true only on a confirmed explicit disabled signal; false on a confirmed enabled signal; null when neither signal is found.
  • isAgeRestricted is null for most Shorts because YouTube omits the isFamilySafe flag on Shorts pages. It is not false by default.
  • CSV / Excel export — nested objects (aboutChannelInfo) and arrays (subtitles, collaborators, descriptionLinks, channelDescriptionLinks) are JSON-serialized into a single column when exported via the Apify Console. This is standard Apify flattening behavior. Use JSON or JSONL export for full fidelity.

FAQ

Do I need a YouTube API key or Google Cloud project?

No. YouTube Shorts Scraper reads the same public data YouTube's own web pages display — no API key, no OAuth, no daily quota.

This Actor only extracts data that is already publicly visible on YouTube — titles, view counts, captions, and channel stats the uploader chose to publish. It does not access private data, bypass logins, or scrape anything behind authentication. See the disclaimer below for your own compliance responsibilities.

Why is commentsTurnedOff sometimes null instead of true or false?

YouTube doesn't always expose an explicit "comments enabled/disabled" signal on the Shorts player response. Rather than guess, this Actor returns null whenever neither a confirmed-enabled nor confirmed-disabled signal is found — a false positive here (wrongly reporting comments as off) is worse for downstream automation than an honest "unknown."

Why is srt sometimes null even though I set subtitleLanguages?

YouTube intermittently gates its caption/transcript endpoint behind a PoToken (proof-of-origin token) requirement — a platform-wide restriction, not an Actor bug. When that happens for a given run, the subtitle track's metadata (language, URL, type) is still returned; only the downloaded SRT text is null. See Limitations.

How many Shorts can I scrape per run?

There's no hard limit from the Actor itself — set maxResultsShorts (per source) and maxItems (global cap) as high as you need. In practice, run size is bounded by your proxy pool and your Pay-Per-Event budget (ACTOR_MAX_TOTAL_CHARGE_USD), both of which you control from the input and run settings.

Can I scrape Shorts by hashtag or topic instead of a channel?

Yes — use searchQueries with your hashtag or keyword (e.g. "#satisfying" or "AI news"). Results come from YouTube's Shorts-filtered search, the same listing the Shorts search tab shows.

Does this Actor work without residential proxies?

It can run with any Apify Proxy group or your own proxy URLs, but YouTube throttles and blocks datacenter IPs aggressively. Residential proxies are strongly recommended for reliable runs at any meaningful volume.


Disclaimer

This Actor is intended for ethical, legitimate data collection and does not extract any private user data such as emails, exact personal locations, or anything not already published by the channel owner or uploader — it only extracts what is publicly visible on YouTube. You are responsible for how you use the extracted data: personal data (even when publicly posted) may be protected under GDPR in the EU and under similar regulations elsewhere. If you intend to process or store personal data at scale, consult your own legal counsel to confirm your use case is compliant.


Support

  • Bug report or feature request: open an issue on the Issues tab of this Actor's Store page.
  • Custom scraping solution: contact the developer through their Apify profile.

Made with ☕ by upadhyay.labs