# YouTube Scraper — Videos, Channels, Comments, Likes & Dislikes (`yugenox/youtube-scraper`) Actor

Scrape YouTube without the API limits. Search videos by keyword or scrape a whole channel by name — with views, likes, dislikes, comments, subtitles, and full metadata. No login, no API key. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/yugenox/youtube-scraper.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** Videos, Social media, Developer tools
- **Stats:** 21 total users, 14 monthly users, 88.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

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 Scraper — Videos, Channels, Comments & More

**Pull YouTube data in bulk — without the API limits, without logging in.** Search for videos, scrape an entire channel by name, extract comments, get likes and dislikes, subtitles, and full metadata. Clean, structured data ready for Excel, JSON, or your app. 🎬

> 🚫 No login · 🔑 No API key · 🤖 No setup · ⚡ Fast · 🌍 Any video, channel, or topic

***

### 🧭 What can it do?

There are **4 simple ways** to use it. Pick whichever fits — you can even mix them in one run.

| You want… | Use this input | Example |
|---|---|---|
| 🔎 Videos about a **topic** | **Search terms** | `"lofi hip hop"` |
| 📺 **A creator's whole channel** | **Channels** | `"Fireship"` |
| 🎧 **A playlist's** videos | **Start URLs** | a playlist link |
| 📹 **Specific videos** | **Start URLs** | one or more video links |
| 🩳 **Shorts** | **Search terms** + `includeShorts` | `"funny cat shorts"` |

Every result comes back with the same rich data: title, views, likes, dislikes, duration, upload date, channel, subscribers, description, **hashtags** and **description links** — plus optional **comments** and **subtitle info**.

Narrow any search with **upload-date filters** (last hour → this year) and **sorting** (relevance, upload date, view count, rating).

***

### 🚀 Quick start (30 seconds)

1. Pick an input — type a **search term**, a **channel name**, or paste a **YouTube link**.
2. Set **Max items** — how many videos you want.
3. (Optional) Turn on **comments**, **dislikes**, or **subtitles**.
4. Click **Start**. Download as JSON, CSV, or Excel.

That's it. No account, no keys, nothing to configure.

***

### 📖 The 4 ways to use it — with examples

#### 1️⃣ Search for videos 🔎

Type keywords, just like the YouTube search bar. Get the top matching videos.

```json
{ "searchTerms": ["apify tutorial"], "maxItems": 50 }
```

#### 2️⃣ Scrape a whole channel 📺 *(great for creators!)*

Just type the **channel name** — no URL needed. Get **every video** with full stats. Perfect for tracking your own channel or a competitor's.

```json
{ "channels": ["Fireship"], "maxItems": 100 }
```

You can also use an `@handle` or a channel URL:

```json
{ "channels": ["@RickAstleyYT", "MrBeast"], "maxItems": 200 }
```

#### 3️⃣ Scrape a playlist 🎧

Paste a playlist link to get all its videos.

```json
{ "startUrls": ["https://www.youtube.com/playlist?list=PLxxxxxx"], "maxItems": 100 }
```

#### 4️⃣ Scrape specific videos 📹

Paste one or more video links.

```json
{ "startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"] }
```

#### ➕ Add comments and dislikes to any of the above 💬👎

```json
{
  "channels": ["Fireship"],
  "maxItems": 50,
  "maxComments": 20,
  "includeDislikes": true
}
```

***

### ⚙️ All input options

| Field | What it does | Default |
|---|---|---|
| 🔎 **Search terms** | Keywords to search on YouTube | — |
| 📺 **Channels** | Channel **name**, `@handle`, or URL → all their videos | — |
| 🔗 **Start URLs** | Video, channel, playlist, or search links | — |
| 🔢 **Max items** | How many videos per search / channel / playlist | `10` |
| 💬 **Max comments per video** | Number of top comments to pull (`0` = none) | `0` |
| 👎 **Include dislikes** | Add an estimated dislike count | `off` |
| 📝 **Include subtitles** | List/attempt subtitle download | `off` |
| 🧾 **Full video details** | Category, keywords, exact duration | `off` |
| 🩳 **Include Shorts** | Also collect YouTube Shorts from search results | `off` |
| 📅 **Upload date** | `any`, `hour`, `today`, `week`, `month`, `year` | `any` |
| ↕️ **Sorting order** | `relevance`, `date`, `views`, `rating` | `relevance` |
| 🔢 **Max Shorts** | Cap Shorts per search (`0` excludes them) | no cap |
| 📡 **Max live streams** | Cap live streams per search (`0` excludes them) | no cap |

*(You need at least one of: Search terms, Channels, or Start URLs.)*

#### 🩳 A note on Shorts

Shorts are **off by default**. YouTube returns them in a separate shelf from normal videos, so
turning `includeShorts` on genuinely changes which videos a search gives you — existing runs keep
their long-form-only results unless you opt in.

```json
{ "searchTerms": ["funny cat shorts"], "maxItems": 20, "includeShorts": true }
```

Shorts rows carry `isShort: true` and a `shortsUrl`. Note that YouTube stops returning the Shorts
shelf when an upload-date filter or a non-default sort order is applied, and `duration` is not
available for Shorts.

#### 📅 Filtering and sorting examples

```json
{ "searchTerms": ["ai news"], "dateFilter": "week", "sortBy": "date", "maxItems": 50 }
```

```json
{ "searchTerms": ["react tutorial"], "sortBy": "views", "maxItems": 100 }
```

Filters apply to **search terms only** — not to direct channel, playlist, or video URLs.

***

### 📤 What you get (output)

**One clean row per video.** Here's a real example:

```json
{
  "id": "dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video)",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
  "viewCount": 1792628321,
  "likes": 19243762,
  "dislikes": 514894,
  "duration": "3:33",
  "date": "Oct 24, 2009",
  "channelName": "Rick Astley",
  "channelUrl": "https://www.youtube.com/@RickAstleyYT",
  "numberOfSubscribers": 4520000,
  "text": "The official video for “Never Gonna Give You Up”...",
  "publishedAt": "2009-10-24",
  "hashtags": ["RickAstley", "NeverGonnaGiveYouUp"],
  "descriptionLinks": [
    { "url": "https://RickAstley.lnk.to/_listenYD", "text": "Listen" }
  ],
  "commentsCount": 3,
  "comments": [
    {
      "author": "@YouTube",
      "text": "can confirm: he never gave us up",
      "likes": 268000,
      "replyCount": 412,
      "publishedTime": "2 years ago"
    }
  ],
  "fromYTUrl": "https://www.youtube.com/@RickAstleyYT",
  "scrapedAt": "2026-07-14T12:00:00.000Z"
}
```

#### 📋 Every field explained

| Field | Description |
|---|---|
| 🆔 `id`, 🔗 `url` | Video ID and link |
| 🏷️ `title` | Video title |
| 🖼️ `thumbnailUrl` | Highest-res thumbnail |
| 👀 `viewCount` | Number of views |
| 👍 `likes` | Exact like count |
| 👎 `dislikes` | Estimated dislikes *(only if enabled)* |
| ⏱️ `duration` | Video length (e.g. `3:33`) |
| 📅 `date` | Upload date, as YouTube displays it (e.g. `Oct 24, 2009`) |
| 📆 `publishedAt` | Upload date normalised to `YYYY-MM-DD` (`null` for relative dates) |
| #️⃣ `hashtags` | Hashtags parsed from the description |
| 🔗 `descriptionLinks` | Links in the description as `{ url, text }` — socials, contact, sponsors |
| 🩳 `isShort`, `shortsUrl` | Present on Shorts *(only when `includeShorts` is on)* |
| 📺 `channelName`, `channelUrl`, `channelId` | Channel info |
| 📈 `numberOfSubscribers` | Channel subscriber count |
| 📝 `text` | Full video description |
| 🏷️ `category`, `keywords` | Category and tags *(with Full details)* |
| 💬 `commentsCount`, `comments` | Comments: author, text, likes, replies, time |
| 🗣️ `availableSubtitles`, `subtitles` | Subtitle languages (+ SRT if available) |
| 🔗 `fromYTUrl` | Where this result came from |
| 📅 `scrapedAt` | When it was scraped |

***

### 💡 Who is this for?

- 🎥 **Creators** — track your channel's performance, or study competitors' videos, views, and engagement
- 📣 **Marketers & brands** — find influencers, monitor mentions, analyze what's trending
- 🔬 **Researchers** — study topics, opinions, and comment sentiment at scale
- 🤖 **AI & data teams** — feed video metadata and comments into your pipelines
- 🏢 **Agencies** — build reports and dashboards from live YouTube data

***

### ❓ FAQ

**Do I need a YouTube account or API key?**
No. It uses YouTube's public data. Nothing to log in to, nothing to set up.

**Can I really scrape a channel just by its name?**
Yes! Type `"Fireship"` (or an `@handle`, or a channel URL) in the **Channels** field and it pulls all their videos with full stats. This is the easiest way to do channel analytics.

**Can it get dislikes?**
Yes, as an **estimate**. YouTube removed public dislikes in 2021, so we use the community *Return YouTube Dislike* database — accurate for older videos, a solid estimate for newer ones. Turn on **Include dislikes** to add it.

**Can I get comments?**
Yes. Set **Max comments per video** to how many you want (e.g. `20`). Each comment includes the author, text, likes, reply count, and time.

**What about subtitles?**
The scraper lists every video's available subtitle **languages**. Downloading the subtitle **text** depends on YouTube availability (they recently locked this behind bot-checks), so it's best-effort.

**How many videos can I scrape?**
Thousands per input. Very large runs may fluctuate depending on YouTube.

**Which proxy should I use?**
The default (Apify Proxy) works great. Residential is available if you ever need it.

***

**Is it legal to scrape YouTube?**
This Actor only collects publicly available data: video, channel and comment data that anyone can see on YouTube without signing in. Collecting publicly available data is generally legal, but you're responsible for how you use it. Results can include channel names and, if you request comments, commenters' public channel names, and that counts as personal data. You must follow privacy laws such as GDPR, PIPEDA and CCPA, as well as YouTube's terms. If you're unsure, check with a lawyer. More on this: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?**
No. Everything comes from pages YouTube shows to any visitor without logging in. It never uses a login, never touches private or restricted accounts, and never reaches password-protected areas.

### 🔒 Notes

- Scrapes **publicly available** data only.
- Please respect copyright and privacy laws (e.g. GDPR) when handling personal data like comments.
- Not affiliated with YouTube.

*Channel, playlist, video, search, and comments are all supported today. Subtitle text download is best-effort. Questions or a bug? Open an issue on the actor's Issues tab.*

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search on YouTube, as you'd type in the search bar. One or more.

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

Channel names, @handles, or channel URLs — pulls all their videos with full data. Great for creator analytics. One or more.

## `startUrls` (type: `array`):

YouTube video, channel, playlist, or search URLs. One or more.

## `maxItems` (type: `integer`):

Max videos per search term.

## `enrich` (type: `boolean`):

Fetch each video's full metadata (likes, description, keywords, category). Off = fast search-feed fields only.

## `includeSubtitles` (type: `boolean`):

Download available subtitles/transcripts (auto + manual) as SRT.

## `includeDislikes` (type: `boolean`):

Add an estimated dislike count via Return YouTube Dislike (3rd-party estimate — YouTube removed public dislikes in 2021).

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

Proxy — RESIDENTIAL required (datacenter IPs hit YouTube bot challenges).

## `maxComments` (type: `integer`):

How many top comments to pull per video (0 = none).

## `dateFilter` (type: `string`):

Only return videos uploaded within this window. Applies to search terms only, not to direct URLs.

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

How YouTube should order search results. Applies to search terms only, not to direct URLs.

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

Also collect YouTube Shorts from search results. Off by default: Shorts change which videos a search returns, so existing runs keep the previous long-form-only behaviour unless you turn this on.

## `maxShorts` (type: `integer`):

Cap how many Shorts (videos 60s or under) to include per search term. Leave empty for no cap; set 0 to exclude Shorts entirely.

## `maxStreams` (type: `integer`):

Cap how many live streams to include per search term. Leave empty for no cap; set 0 to exclude streams entirely.

## Actor input object example

```json
{
  "searchTerms": [
    "lofi hip hop"
  ],
  "channels": [
    "@RickAstleyYT"
  ],
  "maxItems": 10,
  "enrich": true,
  "includeSubtitles": false,
  "includeDislikes": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxComments": 0,
  "dateFilter": "any",
  "sortBy": "relevance",
  "includeShorts": false
}
```

# 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 = {
    "searchTerms": [
        "lofi hip hop"
    ],
    "channels": [
        "@RickAstleyYT"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/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 = {
    "searchTerms": ["lofi hip hop"],
    "channels": ["@RickAstleyYT"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/youtube-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 '{
  "searchTerms": [
    "lofi hip hop"
  ],
  "channels": [
    "@RickAstleyYT"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call yugenox/youtube-scraper --silent --output-dataset

```

## MCP server setup

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