# YouTube Shorts Scraper (`citrine_venus/youtube-shorts-scraper`) Actor

YouTube Shorts Scraper extracts Shorts data including titles, views, likes, comments, upload dates, channels, hashtags, descriptions, captions, and engagement metrics. Ideal for content research, competitor analysis, trend discovery, and AI data pipelines.

- **URL**: https://apify.com/citrine\_venus/youtube-shorts-scraper.md
- **Developed by:** [Data Minds](https://apify.com/citrine_venus) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 📱 YouTube Shorts Scraper — Channel Shorts Data Extractor

**YouTube Shorts Scraper** is a production-grade [Apify Actor](https://docs.apify.com/platform/actors) for extracting **YouTube Shorts data straight from any channel** — no official Data API key, no login, no quota. Give it one or more channels and it returns every Short's **views, likes, comments, hashtags, subtitles and upload date**, plus the **full channel profile** (subscribers, totals, About panel, links) — streamed to your Apify **Dataset** in real time.

> 💡 **Need a custom version, private integration, or a tailored pipeline?** Email **<hello.dataminds@gmail.com>**.

Built for **content researchers**, **marketers**, **influencer/creator-outreach teams**, **social listening & trend analysis**, and **AI/LLM data pipelines** — anyone who needs **clean YouTube Shorts data** without scrolling by hand or wrestling with API quotas.

***

### 📑 Table of contents

- [What is YouTube Shorts Scraper?](#-what-is-youtube-shorts-scraper)
- [Main features](#-main-features)
- [Who is this Actor for?](#-who-is-this-actor-for)
- [What the scraper does](#%EF%B8%8F-what-the-scraper-does)
- [Inputs it accepts](#-inputs-it-accepts)
- [Output format (Dataset)](#-output-format-dataset)
- [Example output (JSON)](#-example-output-json)
- [Error items](#-error-items)
- [Quick start](#-quick-start)
- [Input parameters reference](#%EF%B8%8F-input-parameters-reference)
- [Reliability & anti-blocking](#%EF%B8%8F-reliability--anti-blocking)
- [Integrations & automation](#-integrations--automation)
- [Pricing & how to control cost](#-pricing--how-to-control-cost)
- [Frequently asked questions (FAQ)](#-frequently-asked-questions-faq)
- [Troubleshooting](#%EF%B8%8F-troubleshooting)
- [Help, support & custom builds](#-help-support--custom-builds)
- [Is scraping YouTube legal?](#%EF%B8%8F-is-scraping-youtube-legal)
- [SEO keywords targeted](#-seo-keywords-targeted)

***

### 📱 What is YouTube Shorts Scraper?

The official YouTube Data API charges you in daily quota units, has no dedicated "Shorts" endpoint, and still needs a Google Cloud key to set up.

This Actor is a drop-in replacement that works straight out of the box:

- **Accepts any channel** — a username, an `@handle`, or any channel/Shorts URL.
- **Returns the full Short record** — title, URL, thumbnail, duration, upload date, hashtags, view/like/comment counts, subtitle-track availability.
- **Reads the channel About panel** — description, country, join date, exact subscriber/view/video counts, and every external link.
- **Sorts and filters** — Newest / Popular / Oldest, plus a date cutoff (`YYYY-MM-DD` or "last N days").
- **Streams every finished result to your Dataset** — export to **JSON**, **CSV**, **Excel**, **XML**, or pull them through the [Apify API](https://docs.apify.com/api/v2).

If you have ever needed *"every recent Short from this channel, with view counts and channel details, as clean rows"* — this is the Actor.

***

### ✨ Main features

- 🔗 **Flexible channel input** — plain username, `@handle`, or a full channel/Shorts URL, mixed freely in one bulk field.
- 📱 **Every Short field that matters** — views, likes, comments (count + turned-off flag), duration, upload date, hashtags, description links, members-only/paid-promotion flags.
- 📝 **Subtitle-track metadata** — language, auto-generated flag, and the caption URL for every Short that has one.
- 📺 **Channel enrichment on every row** — subscriber count, total videos/views, join date, country, verified badge and About-panel links, attached to every Short from that channel.
- 🔃 **Sort control** — Newest, Popular or Oldest, matching the chips on the channel's own Shorts shelf.
- 📅 **Date filtering** — an absolute date or a relative "last N days" cutoff, with automatic early-stop once results scanned pass it.
- 🚦 **Automatic network fallback** — direct ➜ datacenter ➜ residential, sticky after the first switch, with a last-resort browser session.
- 📦 **Live dataset writes** and **six prebuilt table views** — Overview, Channel & About, Engagement, Media, Source, Errors.
- 📊 **Run summary** stored in the key-value store, with per-run totals.

***

### 👥 Who is this Actor for?

- 🔬 **Content & trend researchers** — track what's performing on a channel's Shorts shelf without manual scrolling.
- 📈 **Marketers & SEO teams** — mine titles, hashtags and posting cadence for content ideas.
- 🤝 **Creator/influencer outreach** — pull channel details and subscriber counts for partnership lists.
- 👂 **Social listening tools** — monitor a competitor or brand's Shorts output over time.
- 🤖 **AI / LLM data pipelines** — clean, structured Shorts data for RAG and fine-tuning.
- 🗃️ **Analytics & BI teams** — feed a warehouse with view/like/comment time series per channel.
- 🧑‍💻 **Developers** — a dependable YouTube Shorts data source with no quota-limited API key to manage.

***

### ⚙️ What the scraper does

1. **Reads every channel you provide** — one bulk field, any format welcome.
2. **Opens that channel's Shorts shelf** and its About panel for full profile details.
3. **Collects the full Short record** the moment it finds one — title, stats, thumbnail, hashtags.
4. **Saves every finished result straight to your Dataset** — you can watch results land in the Console in real time.
5. **Keeps going even when some channels fail** — a channel with no Shorts, or one that doesn't exist, is logged as a clear error row without stopping the run.
6. **Reports a full run summary** at the end — totals, network route used, and duration.

***

### 📥 Inputs it accepts

| Input type | Example | Notes |
|---|---|---|
| Username | `mrbeast` | No `@` needed |
| Handle | `@mrbeast` | With or without the `@` |
| Channel URL | `https://www.youtube.com/@mrbeast` | Also `/channel/UC…`, `/c/…` |
| Shorts shelf URL | `https://www.youtube.com/@mrbeast/shorts` | Same channel, either form works |

All of the above can be mixed freely in a single run — paste one per line, or upload a file.

***

### 📤 Output format (Dataset)

Every record streams to the dataset the moment it's ready, organized into **six ready-made Console views**:

| View | What it shows |
|---|---|
| ✨ **Overview** | Title, channel, views, likes, comments, date, duration, link |
| 📺 **Channel & About** | Subscriber/view/video totals, country, join date, verified badge, About links |
| 📊 **Engagement** | Views, likes, comments, comments-off, members-only, paid-promotion, age-restricted, hashtags |
| 🎞️ **Media** | Thumbnail, duration, hashtags, subtitle-track metadata, description |
| 🧭 **Source** | Short ID, originating channel input, Shorts shelf link, collection order |
| ⚠️ **Errors** | Any channel that could not be processed, with a clear reason |

***

### 🧾 Example output (JSON)

```json
{
  "title": "World's Largest Tennis Match",
  "translatedTitle": null,
  "type": "shorts",
  "id": "5mU6SRS2Bxo",
  "url": "https://www.youtube.com/shorts/5mU6SRS2Bxo",
  "thumbnailUrl": "https://i.ytimg.com/vi/5mU6SRS2Bxo/maxresdefault.jpg",
  "viewCount": 8568953,
  "date": "2026-08-23T16:00:04.000Z",
  "likes": 202000,
  "channelName": "MrBeast",
  "channelUrl": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
  "channelUsername": "MrBeast",
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "numberOfSubscribers": 515000000,
  "channelTotalVideos": 999,
  "channelTotalViews": 138494809693,
  "isChannelVerified": true,
  "duration": "00:00:51",
  "commentsCount": 21521,
  "commentsTurnedOff": false,
  "hashtags": [],
  "isMembersOnly": false,
  "isPaidContent": false,
  "isAgeRestricted": false,
  "input": "https://www.youtube.com/@mrbeast",
  "fromChannelListPage": "shorts"
}
```

Every record also carries the channel's About-panel details (`channelDescription`, `channelJoinedDate`, `channelDescriptionLinks`, `channelLocation`, `channelAvatarUrl`, `channelBannerUrl`) both at the top level and nested under `aboutChannelInfo`, plus `subtitles` (caption-track metadata) when available.

***

### ⚠️ Error items

When the scraper cannot retrieve data for a given input — for example a channel has no Shorts or does not exist — it pushes an **error item** to the dataset instead of silently skipping it. Normal output items are never affected; you can tell them apart by the presence of an `error` field. Check the ⚠️ **Errors** view in your dataset.

```json
{
  "url": "https://www.youtube.com/@somechannel",
  "input": "somechannel",
  "error": "CHANNEL_HAS_NO_SHORTS",
  "note": "Channel exists but has no Shorts"
}
```

#### Error codes reference

| `error` | Meaning |
|---|---|
| `CHANNEL_DOES_NOT_EXIST` | Channel URL points to a channel that does not exist |
| `NOT_FOUND` | Page was not found / could not be reached |
| `VIDEO_UNAVAILABLE` | A Short is not available (deleted, region-blocked, etc.) |
| `AGE_RESTRICTED` | Channel is age-restricted and cannot be accessed without login |
| `CHANNEL_HAS_NO_SHORTS` | Channel exists but has no Shorts |
| `DATE_FILTER_TOO_STRICT` | Shorts exist but none match the active date filter |
| `NO_RESULTS` | No results collected for this input |
| `NO_VALID_START_URLS` | No valid channels were provided |
| `INVALID_INPUT` | Actor failed due to bad configuration |

***

### 🚀 Quick start

#### Apify Console

1. Log in at [console.apify.com](https://console.apify.com) → **Actors** → open **YouTube Shorts Scraper**.
2. Paste one or more channels (username, `@handle`, or URL).
3. Adjust the Shorts-per-channel limit, sort order or date filter if you want, then click **Start**.
4. Watch the log and the **Output** tab fill up in real time.
5. Export to JSON, CSV or Excel when it's done.

#### API

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~youtube-shorts-scraper/run-sync-get-dataset-items" \
     -H "Authorization: Bearer $APIFY_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"channels":["mrbeast"],"maxResultsShorts":10}'
```

#### Python client

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("YOUR_USERNAME/youtube-shorts-scraper").call(run_input={
    "channels": ["mrbeast"],
    "maxResultsShorts": 10,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["viewCount"])
```

***

### ⚙️ Input parameters reference

#### 🚀 Start here

| Field | Type | Default | Description |
|---|---|---|---|
| `channels` | array | `[]` | Channel usernames, `@handles`, or URLs — bulk input |
| `maxResultsShorts` | integer | `20` | Max Shorts to collect per channel |

#### 🔎 Sorting & filtering

| Field | Type | Default | Description |
|---|---|---|---|
| `sortChannelShortsBy` | string | `NEWEST` | `NEWEST` / `POPULAR` / `OLDEST` |
| `oldestPostDate` | string | — | `YYYY-MM-DD`, or `"N days"` for the last N days |

#### 🌍 Network & reliability

| Field | Type | Default | Description |
|---|---|---|---|
| `proxyConfiguration` | object | no proxy | Automatic direct → datacenter → residential fallback unless overridden |
| `browserFallback` | boolean | `true` | Last-resort browser rescue for stubborn requests |

#### ⚡ Speed & limits

| Field | Type | Default | Description |
|---|---|---|---|
| `maxConcurrency` | integer | `5` | Parallel Short-detail fetches per channel |
| `maxRetries` | integer | `3` | Retries per request on the current network route |
| `maxScanned` | integer | `5000` | Safety cap on Shorts scanned per channel (0 = no cap) |

***

### 🛡️ Reliability & anti-blocking

This Actor starts every run on a **direct connection** — no proxy overhead unless it's actually needed. If YouTube pushes back, the run automatically and transparently escalates:

**Direct connection ➜ datacenter proxy ➜ residential proxy (3 retries) ➜ last-resort browser session**

Once the run escalates to a residential route it **stays there** for every remaining request, so you don't pay for a slower route longer than necessary. Every fallback is logged clearly in the run log. You can also pin your own proxy group in **Proxy configuration** to skip the automatic ladder entirely.

***

### 🔌 Integrations & automation

- **Schedules** — run this Actor daily/weekly to track a channel's newest Shorts.
- **Webhooks** — fire `ACTOR.RUN.SUCCEEDED` to your own endpoint when a run finishes.
- **Zapier / Make / n8n** — feed dataset items straight into a spreadsheet, CRM or Slack alert.
- **MCP / AI agents** — call this Actor as a tool from Claude, Cursor or any MCP-compatible client via [mcp.apify.com](https://mcp.apify.com).
- **REST API** — pull dataset items directly: `GET https://api.apify.com/v2/datasets/{datasetId}/items?format=json`.

***

### 💰 Pricing & how to control cost

This Actor runs on **Apify's pay-per-usage** pricing — you pay for the platform compute, proxy and storage your run consumes, no separate per-result fee. To control cost:

- Start with a low `maxResultsShorts` to sample a channel before a full run.
- Leave **Proxy configuration** on automatic — it only escalates to a paid proxy route when actually needed.
- Set a tight `oldestPostDate` when you only care about recent uploads — the scraper stops early once it passes the cutoff.

***

### ❓ Frequently asked questions (FAQ)

**Does this need a YouTube Data API key or quota?**
No — it works without any Google API key or daily quota limit.

**Can I scrape an entire channel's Shorts?**
Yes — add the channel and set `maxResultsShorts` as high as you need.

**Does it return channel details?**
Yes — every Short carries subscriber count, total videos/views, join date, country and About-panel links from its channel.

**Can I filter by upload date?**
Yes — set `oldestPostDate` to an absolute date or a relative "N days" value.

**Does it work for private or age-restricted channels?**
No — only publicly available YouTube pages are read, same as any anonymous visitor would see.

***

### 🛠️ Troubleshooting

| Symptom | Fix |
|---|---|
| A channel comes back as an error row | Check the ⚠️ **Errors** view for the reason — usually the channel is private, deleted, or has no Shorts |
| Fewer Shorts than `maxResultsShorts` | The channel may simply have fewer Shorts than requested, or the date filter is too strict |
| Run seems slow | Lower `maxConcurrency`, or check if the run escalated to a slower proxy route in the log |

***

### 🆘 Help, support & custom builds

Something not working, or need a custom field, private integration or a bespoke pipeline built on top of this Actor? Email **<hello.dataminds@gmail.com>** — we read every message.

***

### ⚖️ Is scraping YouTube legal?

This Actor only reads **publicly available** YouTube pages — the same pages any anonymous visitor's browser can load. It does not bypass logins, paywalls or private content, and it does not extract private user data such as email addresses. You are responsible for how you use the collected data — respect YouTube's Terms of Service, applicable copyright law, and privacy regulations (GDPR, CCPA, etc.) for your jurisdiction and use case.

***

### 🔑 SEO keywords targeted

youtube shorts scraper, youtube shorts data scraper, youtube shorts api alternative, scrape youtube shorts, youtube shorts channel scraper, youtube shorts downloader data, youtube shorts analytics scraper, youtube shorts view count scraper, youtube shorts hashtag scraper, youtube shorts trend scraper, youtube channel scraper, apify youtube shorts actor, scrape youtube shorts without api key, youtube shorts data extraction tool, youtube shorts engagement scraper.

# Actor input Schema

## `channels` (type: `array`):

🔗 A channel username (no @ needed), an @handle, or any channel URL — for example `mrbeast`, `@mrbeast`, or `https://www.youtube.com/@mrbeast`. Add as many as you like, one per line.

## `maxResultsShorts` (type: `integer`):

🎯 How many Shorts to collect from each channel. Start small (10–20) for a quick sample, raise it for a full harvest.

## `sortChannelShortsBy` (type: `string`):

🔃 Matches the sorting chips on a channel's Shorts tab.

## `oldestPostDate` (type: `string`):

📆 Skip Shorts older than this. Use a date like `2026-01-01`, or a relative value like `7 days` / `30 days` for "published in the last N days". Leave blank for no date filter. Automatically sorts by Newest when set.

## `proxyConfiguration` (type: `object`):

🚦 By default the run starts on a direct connection (no proxy) and automatically switches to a datacenter and then a residential route only if YouTube pushes back. Pick your own route here to override the automatic ladder.

## `browserFallback` (type: `boolean`):

🧭 As a last resort, retry stubborn requests inside a real headless-browser session before giving up.

## `maxConcurrency` (type: `integer`):

🏎️ How many Shorts to fetch full details for at the same time, per channel.

## `maxRetries` (type: `integer`):

🛡️ Attempts before a single request is considered failed on the current network route.

## `maxScanned` (type: `integer`):

🧮 Safety cap on how many Shorts are examined per channel before giving up (mainly relevant when a date filter is set). 0 = no cap.

## Actor input object example

```json
{
  "channels": [
    "mrbeast"
  ],
  "maxResultsShorts": 20,
  "sortChannelShortsBy": "NEWEST",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "browserFallback": true,
  "maxConcurrency": 5,
  "maxRetries": 3,
  "maxScanned": 5000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `overview` (type: `string`):

No description

## `channel` (type: `string`):

No description

## `engagement` (type: `string`):

No description

## `media` (type: `string`):

No description

## `source` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "channels": [
        "mrbeast"
    ],
    "maxResultsShorts": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("citrine_venus/youtube-shorts-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "channels": ["mrbeast"],
    "maxResultsShorts": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("citrine_venus/youtube-shorts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "channels": [
    "mrbeast"
  ],
  "maxResultsShorts": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call citrine_venus/youtube-shorts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,citrine_venus/youtube-shorts-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/i0dR9ELAXAszhc5UO/builds/srDT2crTFX0bMzBM1/openapi.json
