# YouTube Channel Scraper (`donjuan_mime/youtube-channel-scraper`) Actor

Scrape videos, Shorts, and live streams from any YouTube channel: titles, views, durations, publish dates, likes, and channel stats. No API key needed.

- **URL**: https://apify.com/donjuan_mime/youtube-channel-scraper.md
- **Developed by:** [Donjuan](https://apify.com/donjuan_mime) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Channel Scraper: videos, Shorts, and live streams from any channel

YouTube Channel Scraper lists everything a YouTube channel has published: long videos, Shorts, and live streams. For every item you get the title, link, thumbnail, view count, duration, and publish time, plus the channel's name, handle, subscriber count, and verified badge. Turn on video details to add the exact view count, exact publish date, likes, comment count, description, category, and tags.

You don't need a YouTube API key, a Google account, or any code. Add one or more channels, press **Start**, and download the results as JSON, CSV, Excel, XML, or HTML, or pull them into your app through the Apify API.

### What can you do with YouTube channel data?

- **Track competitors.** See what other channels in your niche publish, how often, and which uploads pull the most views.
- **Find top content.** Sort a channel by Popular to get its most viewed videos in one run.
- **Vet creators.** Check subscriber counts, upload frequency, and typical views before you sponsor a channel.
- **Monitor your own channel.** Schedule a daily run and keep a history of views and likes for every upload.
- **Build datasets.** Export titles, descriptions, and tags for content research, SEO analysis, or training data.
- **Watch live schedules.** The Live tab shows streams that are live now and streams scheduled for later.

### What data does YouTube Channel Scraper extract?

| Group | Fields |
|---|---|
| Item | ID, URL, type (video, short, or stream), title, thumbnail, channel tab it came from |
| Stats | views (rounded on the channel page, exact with details), likes and comment count (with details) |
| Time | duration in seconds and as shown, relative publish time ("4d ago"), exact publish time in UTC (with details) |
| Live | live now flag, upcoming flag, scheduled start, "watching" and "waiting" counts as shown |
| Content (with details) | full description, category, tags |
| Channel | channel ID, handle, name, URL, subscribers, verified badge |

### How to scrape a YouTube channel

1. Open the actor and go to the **Input** tab.
2. Add channels. You can write `NASA`, `@NASA`, a channel ID such as `UCLA_DiR1FfKNvjuUpBHmylQ`, or paste a channel link.
3. Pick the sections (Videos, Shorts, Live streams), the sort order, and how many items you want from each.
4. Press **Start**. When the run finishes, open the **Output** tab or press **Export**.

### Input

| Field | Type | Description |
|---|---|---|
| `channels` | array of strings | Channels to scrape: `NASA`, `@NASA`, `UCLA_DiR1FfKNvjuUpBHmylQ`, `https://www.youtube.com/@NASA`, `https://www.youtube.com/channel/UC...`, `/c/...`, or `/user/...` links. Required. |
| `sections` | array | `videos`, `shorts`, `streams`, or any mix. Defaults to `videos`. |
| `sortBy` | string | `latest`, `popular`, or `oldest`. Applies to every section. |
| `maxItemsPerChannel` | integer | The maximum number of items from each section of each channel. |
| `includeVideoDetails` | boolean | Open every video's page for the exact numbers, description, category, and tags. Runs about 20 times slower. |
| `proxyCountryCode` | string | A two-letter country code such as `US` to use Apify residential proxy in that country. `None` uses Apify datacenter proxy. |

#### Input example

```json
{
  "channels": ["@NASA", "veritasium", "https://www.youtube.com/channel/UCsXVk37bltHxD1rDPwtNM8Q"],
  "sections": ["videos", "shorts"],
  "sortBy": "popular",
  "maxItemsPerChannel": 50,
  "includeVideoDetails": false,
  "proxyCountryCode": "None"
}
```

### Output

Every video, Short, or stream becomes one item in the dataset.

#### Output example

A real video from Veritasium with **Include video details** turned on. Long values are shortened.

```json
{
  "id": "NiCgcUTL9_Q",
  "url": "https://www.youtube.com/watch?v=NiCgcUTL9_Q",
  "type": "video",
  "title": "The Absurd Engineering Behind the Internet",
  "description": "Why making glass fibers to send signals was almost impossible. ...",
  "thumbnail": "https://i.ytimg.com/vi/NiCgcUTL9_Q/hq720_custom_3.jpg?...",
  "durationSeconds": 2072,
  "durationText": "34:32",
  "viewCount": 9450655,
  "viewCountText": "9.4M",
  "publishedText": "5d ago",
  "publishedAtISO": "2026-10-12T17:11:45Z",
  "likeCount": 115431,
  "commentCount": 5000,
  "category": "Education",
  "tags": ["veritasium", "science", "physics", "Veritasium"],
  "isLive": false,
  "isUpcoming": false,
  "channel": {
    "id": "UCHnyfMqiRRG1u-2MsSQLbXA",
    "handle": "@veritasium",
    "title": "Veritasium",
    "url": "https://www.youtube.com/@veritasium",
    "subscribers": 21400000,
    "subscribersText": "21.4M subscribers",
    "verified": true
  },
  "section": "videos",
  "input": "@veritasium"
}
```

Without details, the same item has `viewCount: 9400000` (the rounded "9.4M" from the channel page) and no `description`, `publishedAtISO`, `likeCount`, `commentCount`, `category`, or `tags`.

#### Output fields

| Field | Description |
|---|---|
| `id` | YouTube video ID. |
| `url` | Link to the video. Shorts link to `/shorts/`. |
| `type` | `video`, `short`, or `stream`. |
| `title` | The video title. |
| `description` | The full description. Details only. |
| `thumbnail` | The largest thumbnail the channel page offers. |
| `durationSeconds`, `durationText` | Length in seconds and as shown. Shorts get them only with details. Live and upcoming streams have none. |
| `viewCount` | Views. Rounded as the channel page shows them, exact with details. |
| `viewCountText` | Views as shown, or "103 watching" and "4 waiting" on live and upcoming streams. |
| `publishedText` | Relative time such as "4d ago", or "Scheduled for ..." on upcoming streams. Shorts don't show it. |
| `publishedAtISO` | Exact publish time in UTC. Details only. For upcoming streams it holds the scheduled start. |
| `likeCount` | Exact likes. Details only. |
| `commentCount` | Comments, rounded as YouTube shows them (5K becomes 5000). Details only. Missing when comments are off. |
| `category`, `tags` | The uploader's category and tags. Details only. |
| `isLive`, `isUpcoming` | Live now, or scheduled for later. |
| `channel` | Channel ID, handle, name, URL, subscribers (rounded), and verified badge. |
| `section` | The channel tab the item came from. |
| `input` | The channel from your input. |

### Video details

The channel page lists every upload with rounded views and a relative date. With **Include video details** on, the actor also opens each video's page, which adds the exact view count, the exact publish time, likes, the comment count, the description, the category, and the tags.

That's one extra page per video, so a run takes about 20 times longer. In our tests the actor listed about 75 items per second without details and about 4 per second with them.

YouTube limits how many video pages one IP can open in a short time. When a page comes back blocked, the actor retries it from a new IP. If video pages keep coming back blocked, the actor stops asking for details and saves the rest of the items with the data from the channel page, so the run still finishes.

### How many items can I get?

The actor follows a channel's tabs to the end, the same way the site loads more items as you scroll. In our tests it read 100 videos, 90 Shorts, and 100 streams per channel without trouble, and a full run of two channels across all three tabs (731 items) took under 10 seconds.

### Proxy

By default the actor goes through Apify datacenter proxy and switches to a new IP whenever YouTube refuses a request. Set `proxyCountryCode` to a code such as `US` or `DE` to use Apify residential proxy in that country, for example to see the channel as viewers in that country do. Residential proxy needs an Apify plan that includes it.

### How much does it cost?

You pay per item saved to the dataset: **$0.50 per 1,000 items**. Video details don't cost extra per item, they only make the run take longer.

### Export and integrations

- Download results as JSON, CSV, Excel, XML, HTML, or RSS from the **Output** tab.
- Send them to Google Sheets, Slack, Zapier, Make, and other tools through Apify integrations.
- Schedule runs to track a channel over time.
- Start runs and read results from your code through the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/<username>~youtube-channel-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"channels": ["@NASA"], "sections": ["videos"], "maxItemsPerChannel": 30}'
```

### FAQ

#### Do I need a YouTube API key?

No. The actor reads the public channel pages that anyone can open in a browser, so there is no API quota to worry about.

#### Why are the view counts round numbers?

The channel page shows views rounded, such as "561K". Turn on video details to get the exact count from each video's page.

#### Why don't Shorts have a date or duration?

The Shorts tab doesn't show them. Turn on video details to get both.

#### Can I scrape comments or a whole playlist?

Not with this actor. It lists what a channel published on its Videos, Shorts, and Live tabs.

#### What happens with a channel that has no Shorts or Live tab?

The actor writes a line in the log and moves on to the next section.

#### Is it legal to scrape YouTube?

The actor collects only public data that anyone can see without logging in. Public pages can still contain personal data, so make sure you have a legitimate reason to collect it and follow the GDPR and other laws that apply to you. If you're not sure, ask a lawyer.

### Disclaimer

This actor is provided as is, without warranty. You're responsible for how you use it and for following YouTube's terms of service and the laws that apply to you. YouTube isn't affiliated with this actor.

# Actor input Schema

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

Channels to scrape: a handle (NASA), an @handle (@NASA), a channel ID (UCLA_DiR1FfKNvjuUpBHmylQ), or a channel URL. The tab in a URL is ignored; Sections below decides what to scrape.

## `sections` (type: `array`):

Which channel tabs to scrape: long videos, Shorts, live streams, or any mix.

## `sortBy` (type: `string`):

The order YouTube lists each tab in: newest first, most viewed first, or oldest first.

## `maxItemsPerChannel` (type: `integer`):

The maximum number of items from each section of each channel. With Videos and Shorts selected and 50 here, you get up to 50 videos and up to 50 Shorts per channel.

## `includeVideoDetails` (type: `boolean`):

Open each video's page for the exact view count, exact publish time, likes, comment count, description, category, and tags. Runs about 20 times slower.

## `proxyCountryCode` (type: `string`):

Two-letter country code (US, DE, ...) to use Apify residential proxy in that country. "None" uses Apify datacenter proxy.

## Actor input object example

```json
{
  "channels": [
    "@NASA"
  ],
  "sections": [
    "videos"
  ],
  "sortBy": "latest",
  "maxItemsPerChannel": 50,
  "includeVideoDetails": false,
  "proxyCountryCode": "None"
}
```

# Actor output Schema

## `videos` (type: `string`):

One item per video, Short, or stream found on the input channels.

# 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": [
        "@NASA"
    ],
    "maxItemsPerChannel": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("donjuan_mime/youtube-channel-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": ["@NASA"],
    "maxItemsPerChannel": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("donjuan_mime/youtube-channel-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": [
    "@NASA"
  ],
  "maxItemsPerChannel": 50
}' |
apify call donjuan_mime/youtube-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,donjuan_mime/youtube-channel-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/D7ZahdMjo4y7sbKVl/builds/u32zGSya2eayHxmGz/openapi.json
