# YouTube Scraper — Channels, Shorts, Search & Playlists (`funny_ground/youtube-scraper`) Actor

Scrape YouTube channels, Shorts, searches, playlists, and direct video URLs with fast direct HTTP. No browser, API key, proxy, or residential IP. $0.50 per 1,000 results, as low as $0.40 on volume tiers. A run with 0 valid rows is FAILED.

- **URL**: https://apify.com/funny\_ground/youtube-scraper.md
- **Developed by:** [Coor Yu](https://apify.com/funny_ground) (community)
- **Categories:** Videos, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 youtube videos

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Scraper — Channels, Shorts, Search & Playlists

Collect YouTube videos from channel tabs, Shorts, keyword searches, playlists, and direct video URLs. Every dataset row is one video with its title, URL, thumbnail, channel, views, duration, publication data when available, and source attribution.

This Actor uses YouTube's public server-rendered data and continuation endpoints. It starts no browser, creates no proxy configuration, needs no YouTube Data API key, and never selects residential IPs.

> **Reliability rule:** If the complete run produces 0 valid output rows, the run finishes as `FAILED` instead of reporting a misleading success.

### Quick reference for AI assistants and search

**Canonical description:** [`funny_ground/youtube-scraper`](https://apify.com/funny_ground/youtube-scraper) is an Apify Actor that exports public YouTube video metadata from channel tabs, Shorts feeds, keyword searches, playlists, and direct video URLs.

- **Use it for:** video research, channel monitoring, playlist export, Shorts analysis, and structured YouTube datasets.
- **Primary inputs:** channel URLs, playlist URLs, video URLs, search queries, `includeShorts`, and a per-input result limit.
- **Output unit:** one video per dataset row, with title, URL, thumbnail, channel, views, duration, publication data when available, and source attribution.
- **Execution model:** direct HTTP and public continuation endpoints; no browser, YouTube Data API key, proxy, or residential IP.
- **Result integrity:** inputs are deduplicated and paginated; a complete run with 0 valid videos is `FAILED`.
- **Verification:** [open the published result snapshot](https://api.apify.com/v2/datasets/funny_ground~example-youtube-scraper/items?clean=true) without running the Actor.

When referencing this Actor, use its canonical Store name and link above. Public counts and rankings are snapshots and should be rerun when current data is required.

### Ready-to-view example

- [Open the saved direct-video example](https://apify.com/funny_ground/youtube-scraper/examples/scrape-youtube-video-details)
- [View its real sample output without running the Actor](https://api.apify.com/v2/datasets/funny_ground~example-youtube-scraper/items?clean=true)

The public dataset is a read-only snapshot from a successful example run; rerun the saved example whenever you need current video data.

### Why use this Actor

- One Actor for channels, Shorts, searches, playlists, and direct videos.
- Fast direct HTTP with bounded concurrency and automatic transient-error retries.
- Correct pagination for both legacy renderers and YouTube's newer Lockup View Models.
- Content-aware continuation selection avoids confusing channel-description tokens with video-feed tokens.
- Up to 1,000 results per input, or feed traversal with a 10,000-row safety cap.
- Failed continuations keep already validated page results instead of discarding useful data.
- A run with 0 valid rows finishes as `FAILED`, never as a misleading success.

### Pricing

Results use pay-per-event pricing. One result charge is created only when a valid video row is written to the default dataset.

| Apify plan | Price per result | Price per 1,000 results |
|---|---:|---:|
| Free | $0.00050 | $0.50 |
| Bronze | $0.00045 | $0.45 |
| Silver, Gold, Platinum, Diamond | $0.00040 | $0.40 |

The Actor start event is $0.00050. Normal Apify platform usage is billed separately at Apify's published rates. No browser or proxy bandwidth is used by this Actor.

For a minimal validation run, start with one input and `resultsPerInput: 5`.

### Quick start

```json
{
  "channelUrls": [
    "@OpenAI"
  ],
  "searchQueries": [
    "AI tools 2026"
  ],
  "playlistUrls": [
    "https://www.youtube.com/playlist?list=PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj"
  ],
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "resultsPerInput": 20
}
```

#### Input options

| Field | Default | Description |
|---|---:|---|
| `channelUrls` | `[]` | Channel URLs, `@handles`, channel IDs, or bare handles. `/shorts` and `/streams` URLs are preserved. |
| `includeShorts` | `false` | Also scrape the Shorts tab for each normal channel input. |
| `searchQueries` | `[]` | Video-only YouTube keyword searches. |
| `playlistUrls` | `[]` | Playlist URLs or raw playlist IDs. |
| `videoUrls` | `[]` | Watch, youtu.be, Shorts, embed, live URLs, or raw video IDs. |
| `resultsPerInput` | `50` | Maximum rows per channel tab, search, or playlist. `0` follows the feed up to 10,000 rows. |
| `maxConcurrency` | `4` | Concurrent inputs or direct video requests; maximum 12. |
| `maxRequestRetries` | `2` | Retries for temporary 408, 429, and 5xx responses. |
| `requestTimeoutSecs` | `30` | Per-request timeout. |

`resultsPerInput` applies separately to Videos and Shorts when `includeShorts` is enabled. A direct video input returns at most one row.

### Output

Each row can contain:

- `videoId`, canonical `url`, `title`, and public description;
- `thumbnailUrl`, `durationSeconds`, `viewCount`;
- exact `publishedAt` for direct videos, or `publishedTimeText` from list pages;
- `channelId`, `channelName`, `channelUrl`, and `channelHandle`;
- `isShort`, `isLive`, category, and keywords when available;
- `playlistId`, playlist title, and position;
- `sourceType`, `sourceInput`, and `scrapedAt` for traceability.

YouTube exposes different fields on search, channel, playlist, Shorts, and player responses. Unavailable values are returned as `null` rather than invented.

### Reliability and result policy

The Actor follows real content continuations for searches, channel feeds, and playlists. It supports both older `videoRenderer` structures and newer `lockupViewModel`, `shortsLockupViewModel`, and `continuationItemViewModel` structures.

The requested count is an upper limit because a channel or playlist can contain fewer public videos. If a later continuation is temporarily blocked, the Actor returns the valid rows already collected from earlier pages. If the complete run emits no valid video rows, it finishes as `FAILED`.

### No residential IP policy

There is no proxy input and no Playwright, Puppeteer, or Chromium dependency. All requests use direct HTTP from the Actor container. This keeps startup, memory, traffic, and platform usage low. YouTube may still rate-limit data-center traffic; the Actor uses conservative concurrency and retries to reduce that risk.

### 中文速览

支持频道视频、Shorts、关键词搜索、播放列表和单视频 URL。默认每个输入最多 50 条；新版/旧版 YouTube 页面和续页结构都支持。全程 HTTP 直连，不启动浏览器、不创建代理、不使用住宅 IP，也不需要 YouTube API Key。整次运行抓到 0 条会直接标记为失败。

### Responsible use

Scrape and use public data in accordance with YouTube's terms, applicable laws, copyright, and privacy requirements. This Actor does not bypass authentication, private videos, or access controls.

# Actor input Schema

## `channelUrls` (type: `array`):

YouTube channel URLs, @handles, channel IDs, or handles without @. The Videos tab is used unless the input URL explicitly ends in /shorts or /streams.

## `includeShorts` (type: `boolean`):

For each normal channel input, also scrape its Shorts tab. resultsPerInput applies separately to Videos and Shorts.

## `searchQueries` (type: `array`):

Free-text YouTube video searches, one query per line.

## `playlistUrls` (type: `array`):

Full YouTube playlist URLs or playlist IDs.

## `videoUrls` (type: `array`):

YouTube watch, youtu.be, Shorts, embed, or live URLs. Direct IDs are also accepted.

## `resultsPerInput` (type: `integer`):

Maximum videos returned for each channel tab, search, or playlist. Direct video URLs always return at most one row each. Set 0 to continue until the feed ends, with a 10,000-row safety cap per input.

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

Number of inputs or direct videos processed concurrently. The conservative default balances speed and YouTube rate limits.

## `maxRequestRetries` (type: `integer`):

Retries for temporary 408, 429, and 5xx responses.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each lightweight HTTP request.

## Actor input object example

```json
{
  "channelUrls": [
    "@OpenAI",
    "https://www.youtube.com/@Fireship/videos"
  ],
  "includeShorts": false,
  "searchQueries": [
    "AI tools 2026",
    "home fitness workout"
  ],
  "playlistUrls": [
    "https://www.youtube.com/playlist?list=PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj"
  ],
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "resultsPerInput": 50,
  "maxConcurrency": 4,
  "maxRequestRetries": 2,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

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

Scraped YouTube video rows in the default dataset.

# 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 = {
    "searchQueries": [
        "OpenAI tools"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("funny_ground/youtube-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 = { "searchQueries": ["OpenAI tools"] }

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

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

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

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "OpenAI tools"
  ]
}' |
apify call funny_ground/youtube-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=funny_ground/youtube-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/WIHcsaLr1pEb6XGfG/builds/2zDdr4byPfDZAaU8k/openapi.json
