# YouTube Scraper: Channels, Videos, Transcripts & Comments (`socialhz/youtube-scraper`) Actor

Scrape YouTube channels and videos — subscriber and view counts, full video lists with pagination, complete transcripts, and comments with replies. Transcripts included, not a paid add-on. No login. Pricing: videos $1.79/1K, video details with transcript $2.49/1K, comments $1.49/1K.

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

## Pricing

from $1.79 / 1,000 videos

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: Channels, Videos, Transcripts & Comments

Give it a list of YouTube channels and video links. Get back each channel's full statistics and video history, each video's details and **complete transcript**, and comments with their replies — in one run, with no YouTube login and no API key of your own.

**Transcripts are included in the video price.** They are not a paid add-on here.

Mix channels and videos in the same list. Each entry is routed automatically.

Built for AI and content pipelines, creator vetting, competitor research and audience analysis.

***

### What it does

- **Channels** — subscriber count, **lifetime view total**, how many videos exist, creation date, country, banner, links to their other social accounts
- **Video history with real pagination** — YouTube returns 30 videos per page and this Actor keeps going, so you can pull a channel's back catalogue rather than just its latest page
- **Full transcripts** — the spoken content as plain text, with the caption language, ready to feed a model or a search index
- **Video detail** — views, likes, comments, length, category, language, keywords, hashtags, age restriction, live and unlisted flags
- **Comments with replies** — author, text, likes, reply count, and whether a comment is pinned or written by the creator
- **Videos or Shorts** — a channel's long-form feed and its Shorts feed are separate, and you choose which to read
- **Title and description kept apart** — YouTube serves them as one blob; this Actor splits them so the title column is a title
- **No duplicates** — paginated pages overlap, and repeats are dropped before they are ever charged

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `targets` | array | — | **Required.** Channels and videos, mixed freely. Max `200` per run |
| `maxVideosPerChannel` | integer | `30` | How far back to go per channel. 30 is one page |
| `contentType` | select | `video` | Read a channel's **Videos** or its **Shorts** |
| `includeTranscript` | boolean | `true` | Return the transcript with each video you supply |
| `includeComments` | boolean | `false` | Return comments on videos you supply |
| `maxCommentsPerVideo` | integer | `20` | The first 20 arrive free with the video |

**Accepted entries**

```
Channels   @MrBeast
           MrBeast
           youtube.com/@MrBeast
           youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA
           UCX6OQ3DkcsbYNE6H8uQQuVA

Videos     youtube.com/watch?v=dQw4w9WgXcQ
           youtu.be/dQw4w9WgXcQ
           youtube.com/shorts/_JUlWtSCNbs
```

#### Example input

```json
{
  "targets": [
    "@MrBeast",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxVideosPerChannel": 60,
  "includeTranscript": true,
  "includeComments": false
}
```

***

### Output

One record per entry, carrying `type` (`channel` or `video`), `label` and `status`.

#### Channel records

| Field | Type | Description |
|---|---|---|
| `channelId`, `handle`, `displayName` | string | null | Identity |
| `description` | string | null | About-panel text |
| `subscriberCount` | number | null | Subscribers |
| `totalViews` | number | null | **Lifetime views across the channel** |
| `videoCount` | number | null | How many videos the channel has published |
| `createdAt`, `location` | string | null | When and where |
| `isVerified`, `isFamilySafe`, `privacyStatus` | | Status flags |
| `profileImageUrl`, `bannerImageUrl` | string | null | Images |
| `externalLinks`, `keywords` | array | Their other accounts, and channel keywords |
| `videos` | array | Each with title, description, link, views, likes, comments, publish date, thumbnail, hashtags |
| `videosReturned`, `morePagesAvailable` | | How many you got, and whether more exist |

Put `subscriberCount` and `totalViews` beside `videoCount` and you have average views per video — the quickest read on whether an audience is real.

#### Video records

| Field | Type | Description |
|---|---|---|
| `videoId`, `url`, `title`, `description` | string | null | Identity and text, kept separate |
| `publishedAt` | string | null | ISO 8601 UTC |
| `viewCount`, `likeCount`, `commentCount` | number | null | Engagement |
| `channelName`, `channelHandle`, `channelId` | string | null | Who published it |
| `durationSeconds`, `category`, `language` | | Length, YouTube category, language |
| `keywords`, `hashtags`, `mentions` | array | Metadata |
| **`transcript`** | string | null | **The spoken content as plain text** |
| `transcriptLanguage`, `subtitles` | | Caption language and tracks |
| `isLive`, `isPrivate`, `isUnlisted`, `ageRestriction` | | Status flags |
| `comments` | array | Author, text, likes, reply count, pinned and creator flags |
| `commentsReturned`, `moreCommentsAvailable` | | How many you got, and whether more exist |

Every record also carries `status`: `ok`, `not_found` for a channel or video that is not publicly available, or `unavailable` if the source could not be reached.

***

### Pricing

| Event | Price |
|---|---|
| Video from a channel feed | $1.79 per 1,000 |
| Channel looked up | $1.79 per 1,000 |
| Video detail, **transcript included** | $2.49 per 1,000 |
| Extra comment beyond the first 20 | $1.49 per 1,000 |
| Run start | $0.005 per run |

The same price applies on every Apify plan.

An entry that is not a YouTube channel or video is rejected before any lookup and costs nothing, as are duplicates. Repeated videos and comments across paginated pages are dropped before they are charged.

#### Worked examples

Totals are rounded to the nearest cent.

**Channel snapshot — 10 channels, 30 videos each**
10 × $0.00179 + 300 × $0.00179 + $0.005 = **≈$0.56**

**Back catalogue — one channel, 600 videos**
1 × $0.00179 + 600 × $0.00179 + $0.005 = **≈$1.08**

**Transcript pull — 500 videos with transcripts**
500 × $0.00249 + $0.005 = **$1.25**

Set **Maximum cost per run** in the run options to cap spend. The Actor stops cleanly at that ceiling and returns everything it charged for.

***

### Good to know

**This source is deliberate rather than fast.** A channel page takes eight to twenty seconds, so a deep pull is a long run — 600 videos is twenty pages and several minutes. Requests are given ninety seconds before being retried, which is why a slow source costs you a slower run rather than an empty one. Set the run timeout generously for large jobs.

**The first 20 comments come free with the video.** Leaving the comment limit at 20 adds nothing to your bill. Ask for more and only the extra pages are charged.

**Transcripts depend on captions existing.** Where a video has no captions in any form, `transcript` comes back null. Most substantial channels caption their content.

**You supply the channels and videos.** There is no keyword search — this Actor reads what you point it at.

***

### Tips

- **Check the ratio before you pay a creator.** Lifetime views divided by video count, against subscriber count, exposes a bought audience faster than any single number.
- **Pull transcripts in bulk, then search them.** One run over a channel's catalogue gives you a corpus you can query offline without touching YouTube again.
- **Comments are unfiltered product research.** Sort by like count and the top comments are the objections and praise an audience actually agrees on.
- **Shorts and Videos are different businesses.** Run both feeds for the same channel and compare — many creators perform very differently across the two.
- **Start shallow.** One page per channel is enough to rank a list; go deep only on the channels that survive that cut.

***

### Support

Report a problem through the **Issues** tab on this Actor's page. Issues are reviewed regularly.

When reporting, please include the run ID, the input you used, and what you expected.

For volume enquiries, custom requirements, or anything not specific to a single run, email **socialhtz@gmail.com**.

# Changelog

This Actor's version history is a separate document: https://apify.com/socialhz/youtube-scraper/changelog.md

# Actor input Schema

## `targets` (type: `array`):

Mix channels and videos freely, one per line. Channels can be a handle like @MrBeast, a channel URL, or a canonical UC… ID. Videos can be a normal watch link, a youtu.be link, or a Shorts link. Anything else is skipped and costs you nothing. Up to 200 entries per run.

## `maxVideosPerChannel` (type: `integer`):

How far to go back through each channel. YouTube returns 30 videos per page, so 30 is one page, 300 is ten pages. Each page takes 8-20 seconds, so a deep pull is a long run. Videos are the priced unit — you are charged for what you receive.

## `contentType` (type: `string`):

Which feed to read from each channel. A channel's long-form videos and its Shorts are separate feeds; this picks one. Ignored for video links you supply directly.

## `includeTranscript` (type: `boolean`):

Applies to video links you supply. Returns the spoken content as plain text, along with the language it was captioned in. Included in the video price — there is no separate transcript charge.

## `includeComments` (type: `boolean`):

Applies to video links you supply. The first comments arrive with the video at no extra charge; ask for more than that and the extra pages are charged per comment.

## `maxCommentsPerVideo` (type: `integer`):

Only used when comments are switched on. YouTube returns 20 per page. The first 20 come free with the video, so leaving this at 20 adds nothing to your bill.

## Actor input object example

```json
{
  "targets": [
    "@MrBeast",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxVideosPerChannel": 30,
  "contentType": "video",
  "includeTranscript": true,
  "includeComments": false,
  "maxCommentsPerVideo": 20
}
```

# Actor output Schema

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

One record per entry — a channel with its videos, or a single video with its transcript and comments.

# 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 = {
    "targets": [
        "@MrBeast",
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("socialhz/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 = { "targets": [
        "@MrBeast",
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("socialhz/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 '{
  "targets": [
    "@MrBeast",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ]
}' |
apify call socialhz/youtube-scraper --silent --output-dataset

```

## MCP server setup

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