# Youtube Channel Scraper Pro (`skcho/youtube-channel-scraper-pro`) Actor

Youtube Channel Scraper Pro

- **URL**: https://apify.com/skcho/youtube-channel-scraper-pro.md
- **Developed by:** [seungkyu cho](https://apify.com/skcho) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Channel Scraper Pro 🚀

A high-performance, reliable Apify Actor for scraping YouTube channel videos — including Long-Form and Shorts — with advanced filtering and infinite scroll support.

🔗 **Apify Actor URL:** [https://apify.com/skcho/youtube-channel-scraper-pro](https://apify.com/skcho/youtube-channel-scraper-pro)

---

### ✨ Key Features

- **🔄 Infinite Scroll (Pagination):** Automatically scrolls through the entire channel page using a real browser — no 30-video limit.
- **🗂️ Long-Form & Shorts Separation:** Precisely scrape and categorize videos by type.
- **📦 Rich Data Extraction:** Titles, View Counts, Upload Dates, Durations, HQ Thumbnails, and Animated WebP Previews — all extracted out of the box.
- **👍 Optional Like Count Extraction:** A lightweight, high-concurrency HTTP-based fetcher grabs like counts at **~430 videos/min** without launching extra browsers.
- **🎯 Precision Filtering:** Filter by minimum views, likes, upload date range, and more.
- **🧠 Hybrid Architecture:** `PlaywrightCrawler` handles real-browser scrolling; `HttpCrawler` handles likes — minimizing memory usage and maximizing speed.

---

### ⚡ Performance

| Scenario | Speed |
| :--- | :--- |
| Channel scroll + data extract (100 videos) | ~15 seconds |
| Like count fetch (per 100 videos, `fetchLikes: true`) | ~15 seconds |
| **Total for 100 videos with likes** | **~30 seconds** |

> Likes are fetched at **~430 requests/min** in parallel via lightweight HTTP requests — **no extra browser needed**.

---

### 🛠️ Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `channelUrls` | `Array<String>` | *(Required)* | YouTube channel URLs to scrape (e.g., `https://www.youtube.com/@mkbhd`). Multiple channels supported. |
| `videoType` | `Enum` | `"ALL"` | Which video type to scrape: `"ALL"`, `"LONG_FORM"`, or `"SHORTS"`. |
| `minUploadDate` | `String` | `""` | Only include videos uploaded **on or after** this date. Format: `YYYY-MM-DD`. |
| `maxUploadDate` | `String` | `""` | Only include videos uploaded **on or before** this date. Format: `YYYY-MM-DD`. |
| `minViews` | `Integer` | `0` | Only include videos with at least this many views. (e.g., `1000000` for 1M+). |
| `maxItemsPerChannel` | `Integer` | `100` | Maximum videos to scrape **per channel**. Uses infinite scroll to exceed YouTube's default 30-video page limit. |
| `fetchLikes` | `Boolean` | `false` | If enabled, fetches exact Like counts for every video via fast parallel HTTP requests. Adds ~15s per 100 videos. |
| `minLikes` | `Integer` | `0` | *(Requires `fetchLikes: true`)* Only include videos with at least this many likes. |

---

### 📄 Output Data Structure

Each video is pushed as a JSON object to the Apify Dataset:

```json
{
  "channelName": "Marques Brownlee",
  "channelUrl": "https://www.youtube.com/@mkbhd",
  "videoId": "eFeDpUVEy48",
  "videoUrl": "https://www.youtube.com/watch?v=eFeDpUVEy48",
  "title": "The Biggest Android Update Ever",
  "type": "LONG_FORM",
  "uploadDateText": "8 days ago",
  "viewCount": 4099999,
  "durationText": "12:59",
  "thumbnailUrl": "https://i.ytimg.com/vi/eFeDpUVEy48/hqdefault.jpg",
  "animatedThumbnailUrl": "https://i.ytimg.com/an_webp/eFeDpUVEy48/mqdefault_6s.webp",
  "likeCount": 125000
}
````

#### Field Reference

| Field | Type | Description |
| :--- | :--- | :--- |
| `channelName` | `String` | Official channel display name |
| `channelUrl` | `String` | Input channel URL |
| `videoId` | `String` | YouTube video ID |
| `videoUrl` | `String` | Full `youtube.com/watch?v=...` URL |
| `title` | `String` | Video title |
| `type` | `String` | `"LONG_FORM"` or `"SHORTS"` |
| `uploadDateText` | `String` | Relative upload date (e.g., `"8 days ago"`) |
| `viewCount` | `Integer` | Parsed integer view count |
| `durationText` | `String` | Video duration string (e.g., `"12:59"`) |
| `thumbnailUrl` | `String` | Highest-quality static thumbnail URL |
| `animatedThumbnailUrl` | `String` | 3-second animated WebP preview URL |
| `likeCount` | `Integer` | Like count — present only when `fetchLikes: true` |

***

### ⚙️ How It Works (Architecture)

This actor uses a **two-phase hybrid architecture** to maximize both stability and speed:

#### Phase 1 — Scroll & Extract (PlaywrightCrawler)

A real Chromium browser navigates to the channel's `/videos` and `/shorts` tabs. It automatically scrolls down the page, triggering YouTube's infinite scroll to load more videos, until `maxItemsPerChannel` is reached or the page end is detected. Video metadata is then extracted directly from the rendered DOM.

**Browser optimizations:**

- Blocks unnecessary resources (images, fonts, media) to reduce memory usage
- Disables GPU, extensions, and background services
- Anti-bot fingerprint masking (`navigator.webdriver` suppressed)

#### Phase 2 — Like Count Fetch (HttpCrawler, Optional)

If `fetchLikes` is enabled, up to **20 concurrent lightweight HTTP requests** are made to individual `youtube.com/watch?v=...` pages. Like counts are extracted by parsing the embedded `ytInitialData` JSON object — **no browser required**. This runs at ~430 requests/min.

***

### 🤝 Support & Issues

Found a bug or have a feature request? Please reach out via the Apify Issues tab!

# Actor input Schema

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

List of YouTube channel URLs to scrape (e.g., https://www.youtube.com/@mkbhd).

## `videoType` (type: `string`):

Type of videos to scrape.

## `minUploadDate` (type: `string`):

Filter videos uploaded ON or AFTER this date. Format: YYYY-MM-DD. Leave empty to ignore.

## `maxUploadDate` (type: `string`):

Filter videos uploaded ON or BEFORE this date. Format: YYYY-MM-DD. Leave empty to ignore.

## `minViews` (type: `integer`):

Only scrape videos with at least this many views.

## `fetchLikes` (type: `boolean`):

If enabled, the scraper will visit each video page individually to fetch like counts. WARNING: This will significantly increase scraping time and consume more Apify credits.

## `minLikes` (type: `integer`):

Only scrape videos with at least this many likes.

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

Maximum number of videos to scrape per channel (0 for unlimited).

## `maxDaysOld` (type: `integer`):

Stop scraping videos uploaded older than this many days. Leave 0 to disable.

## Actor input object example

```json
{
  "channelUrls": [
    "https://www.youtube.com/@mkbhd"
  ],
  "videoType": "ALL",
  "minViews": 0,
  "fetchLikes": false,
  "minLikes": 0,
  "maxItemsPerChannel": 5,
  "maxDaysOld": 0
}
```

# 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 = {
    "channelUrls": [
        "https://www.youtube.com/@mkbhd"
    ],
    "minUploadDate": "",
    "maxUploadDate": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("skcho/youtube-channel-scraper-pro").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 = {
    "channelUrls": ["https://www.youtube.com/@mkbhd"],
    "minUploadDate": "",
    "maxUploadDate": "",
}

# Run the Actor and wait for it to finish
run = client.actor("skcho/youtube-channel-scraper-pro").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 '{
  "channelUrls": [
    "https://www.youtube.com/@mkbhd"
  ],
  "minUploadDate": "",
  "maxUploadDate": ""
}' |
apify call skcho/youtube-channel-scraper-pro --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Youtube Channel Scraper Pro",
        "description": "Youtube Channel Scraper Pro",
        "version": "0.0",
        "x-build-id": "eZqYHk3qqHkW06MiC"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/skcho~youtube-channel-scraper-pro/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-skcho-youtube-channel-scraper-pro",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/skcho~youtube-channel-scraper-pro/runs": {
            "post": {
                "operationId": "runs-sync-skcho-youtube-channel-scraper-pro",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/skcho~youtube-channel-scraper-pro/run-sync": {
            "post": {
                "operationId": "run-sync-skcho-youtube-channel-scraper-pro",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "channelUrls",
                    "videoType"
                ],
                "properties": {
                    "channelUrls": {
                        "title": "Channel URLs",
                        "type": "array",
                        "description": "List of YouTube channel URLs to scrape (e.g., https://www.youtube.com/@mkbhd).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "videoType": {
                        "title": "Video Type",
                        "enum": [
                            "ALL",
                            "LONG_FORM",
                            "SHORTS"
                        ],
                        "type": "string",
                        "description": "Type of videos to scrape.",
                        "default": "ALL"
                    },
                    "minUploadDate": {
                        "title": "Minimum Upload Date",
                        "type": "string",
                        "description": "Filter videos uploaded ON or AFTER this date. Format: YYYY-MM-DD. Leave empty to ignore."
                    },
                    "maxUploadDate": {
                        "title": "Maximum Upload Date",
                        "type": "string",
                        "description": "Filter videos uploaded ON or BEFORE this date. Format: YYYY-MM-DD. Leave empty to ignore."
                    },
                    "minViews": {
                        "title": "Minimum Views",
                        "type": "integer",
                        "description": "Only scrape videos with at least this many views.",
                        "default": 0
                    },
                    "fetchLikes": {
                        "title": "Fetch Like Counts (Slower)",
                        "type": "boolean",
                        "description": "If enabled, the scraper will visit each video page individually to fetch like counts. WARNING: This will significantly increase scraping time and consume more Apify credits.",
                        "default": false
                    },
                    "minLikes": {
                        "title": "Minimum Likes",
                        "type": "integer",
                        "description": "Only scrape videos with at least this many likes.",
                        "default": 0
                    },
                    "maxItemsPerChannel": {
                        "title": "Maximum Items Per Channel",
                        "type": "integer",
                        "description": "Maximum number of videos to scrape per channel (0 for unlimited).",
                        "default": 5
                    },
                    "maxDaysOld": {
                        "title": "Maximum Days Old (e.g. 30 for 1 month)",
                        "type": "integer",
                        "description": "Stop scraping videos uploaded older than this many days. Leave 0 to disable.",
                        "default": 0
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
