# YouTube Scraper – Videos, Shorts, Channels & Search (`brii3343/youtube-scraper`) Actor

Scrape YouTube search results, channels, playlists, Shorts and hashtags with complete data on every row: exact publish time, views, likes, exact comment count, tags, category and channel stats. Newest-first sorting that really works, optional comments. $2.50 per 1,000 videos.

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

## Pricing

from $1.60 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 — complete video data from search, channels, playlists, Shorts and hashtags

Get YouTube videos, Shorts and live streams with **every field filled in on every row**: exact publish date and time, duration, views, likes, **exact comment count**, tags, category, hashtags, description and channel data (name, handle, subscribers, verified). From search terms with all YouTube filters, channels (Videos, Shorts, Live tabs), playlists, hashtag pages, search result links and single videos. Optionally with comments.

#### Why this Actor

- **Complete rows, not just what the list shows.** A YouTube search or channel page only shows title, views and "3 weeks ago". This Actor opens every video, so each row from a search, channel or playlist has the exact publish time, likes, comment count, tags and category too. In our tests **1,014 videos out of 1,018** (99.6%) from 25 searches, 5 channels and 3 playlists came back with full details.
- **Checked against the real pages.** We compared 30 videos field by field with their YouTube pages: title, publish date and time, duration, category, tags, views, likes, channel and subscribers matched **30 out of 30**.
- **Exact comment count.** Where YouTube shows a rounded "2.4K comments", you get the exact number (for example `2437`).
- **Newest first and Most viewed that really work.** YouTube no longer sorts search results by upload date and sorts by views only roughly. With these options the Actor reads the whole result list of the search (up to 1,000 videos) and sorts it itself: in our tests 0 videos out of order in the top 20.
- **Big channels and playlists.** A channel of 1,000 videos came back complete, in date order, without duplicates. Playlists go past the first 100 videos.
- **Only new videos.** `publishedAfter` (`2026-09-01` or `7 days`) keeps only recent videos; on channels sorted newest first the Actor stops as soon as it reaches older videos. Older videos are **not charged**.
- **Clear errors, never charged.** Wrong links, deleted videos, private playlists and channels that do not exist get a status row with the reason, free.

#### Use cases

- **Influencer and creator research**: every video of a channel with views, likes, comments and engagement over time.
- **Brand and competitor monitoring**: the newest videos for your keywords every day (`Newest first` + `Upload date: Today`).
- **Content and SEO research**: titles, tags, categories and hashtags of the top videos for a topic, in any country and language.
- **Trend analysis**: Shorts and hashtag pages, with exact numbers.
- **Comment analysis and AI**: comments with author, likes, replies, pinned and "hearted by creator", ready for sentiment analysis or LLM pipelines.

#### Input

| Field | Description |
|---|---|
| Search terms | One search per line, as you would type it on YouTube. |
| YouTube URLs | Videos, Shorts, channels (`/@handle`, `/channel/UC…`, `/c/…`, `/user/…`, optionally ending in `/videos`, `/shorts`, `/streams`), playlists, search result pages (their filters are kept) and hashtag pages (`/hashtag/cooking`). |
| Max videos per search or URL | Default 20. For channels, per tab. |
| Full details for every video | On by default: exact publish time, duration, tags and category on every row. Off: faster and cheaper for us, views, likes, comment count, date, description and channel data are still included. |
| Search filters | Sort (Relevance, Newest first, Most viewed), upload date (last hour, today, this week, this month, this year), type (videos, Shorts, live now), duration (under 4, 4-20, over 20 minutes), features (HD, 4K, subtitles, Creative Commons, live, 360°, HDR, VR180, 3D, location, purchased). |
| Channel tabs, channel order | Videos, Shorts, Live; newest first, most popular or oldest first. |
| Only videos published after | A date or an age (`7 days`, `2 weeks`, `3 months`). |
| Comments per video | 0 = no comments. Top comments or newest first. |
| Country, language | Country for ranking and availability (`US`, `GB`, `DE`, `IN`…), language of the search (`en`, `de`, `es`…). |

Example input:

```json
{
  "searchQueries": ["iphone 17 review"],
  "startUrls": [
    { "url": "https://www.youtube.com/@veritasium" },
    { "url": "https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab" }
  ],
  "maxResults": 50,
  "sortBy": "date",
  "uploadDate": "week",
  "publishedAfter": "7 days",
  "maxComments": 0
}
```

#### Output

One row per video, Short or live stream. Real output (description and lists shortened here):

```json
{
  "type": "video",
  "id": "JsBZOcqZerk",
  "url": "https://www.youtube.com/watch?v=JsBZOcqZerk",
  "title": "The Insane Real Engineering of the Nazi Enigma Machine",
  "description": "How was the \"unbreakable\" enigma cracked? ...",
  "publishedAt": "2026-09-21T17:49:57.000Z",
  "publishedDate": "2026-09-21",
  "publishedTimeText": "7 days ago",
  "durationSeconds": 2861,
  "duration": "47:41",
  "viewCount": 12452633,
  "likeCount": 106743,
  "commentCount": 5839,
  "commentsTurnedOff": false,
  "hashtags": [],
  "tags": ["veritasium", "science", "physics", "Veritasium"],
  "category": "Education",
  "thumbnailUrl": "https://i.ytimg.com/vi/JsBZOcqZerk/hqdefault.jpg",
  "isLive": false,
  "isUpcoming": false,
  "isFamilySafe": true,
  "isUnlisted": false,
  "isMembersOnly": false,
  "channelId": "UCHnyfMqiRRG1u-2MsSQLbXA",
  "channelName": "Veritasium",
  "channelHandle": "@veritasium",
  "channelUrl": "https://www.youtube.com/@veritasium",
  "channelSubscribers": 21300000,
  "channelVerified": true,
  "collaborators": null,
  "channelDescription": "An element of truth - videos about science, education, and anything else we find...",
  "channelCountry": "United States",
  "channelJoinedDate": "2010-07-21",
  "channelTotalViews": 4611185593,
  "channelTotalVideos": 536,
  "channelLinks": [{ "title": "Buy SNATOMS", "url": "https://snatoms.com/" }],
  "source": "channel",
  "input": "https://www.youtube.com/@veritasium",
  "position": 1,
  "detailsComplete": true,
  "scrapedAt": "2026-09-29T10:49:18.385Z"
}
```

- `type`: `video`, `short` or `stream` (live now, upcoming or past live).
- Live streams also have `liveViewers` (while live), `liveStartedAt`, `liveEndedAt`.
- Channel fields `channelDescription`, `channelCountry`, `channelJoinedDate`, `channelTotalViews`, `channelTotalVideos`, `channelLinks` are added when the source is a channel.
- `collaborators`: for videos made by several channels, all of them with id, name, handle and subscribers (the first one is the main channel).
- With comments on, `comments` holds `text`, `author`, `authorChannelId`, `authorIsChannelOwner`, `authorIsVerified`, `publishedTimeText`, `likeCount`, `replyCount`, `isPinned`, `isHearted`.
- Status rows (`status`: `invalid_input`, `not_found`, `unavailable`, `no_results`, `error`) explain what could not be read, and are not charged.

#### Pricing

Pay per result: **$2.50 per 1,000 videos** (lower on higher Apify plans) and **$1.20 per 1,000 comments**. Status rows and videos filtered out by `publishedAfter` are free. You can set a maximum cost per run: the Actor stops exactly at your limit, and every video is charged together with its comments, so you get complete rows (only the last video may have fewer comments).

#### Good to know

- **Numbers YouTube does not make public stay empty (`null`)**: likes hidden by the creator (and on videos made for kids), subscribers hidden by the channel, views of members-only videos, comments turned off. Subscribers are rounded as YouTube shows them (`21.3M` → `21300000`).
- **A search gives what YouTube lists**: usually 300-600 videos per search. For more, use several related search terms or the upload date filter.
- **Speed**: about 1,000 videos in 7-12 minutes with full details, 500 videos in about 35 seconds without.
- **Live streams** have no duration while live; members-only videos have no public view count.

#### FAQ

**Can I get the transcript or subtitles?** Use our [YouTube Transcript Scraper](https://apify.com/brii3343/youtube-transcript-scraper), which gives the full transcript with timestamps in any language.

**Can I scrape only Shorts?** Yes: in a search choose type "Shorts only", or give a channel URL ending in `/shorts`, or choose the Shorts tab.

**Does it need my YouTube account or cookies?** No. It reads only public data.

# Actor input Schema

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

One search per line, typed as you would in the YouTube search bar. Use the filters below to narrow the results.

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

Links to videos, Shorts, channels (<code>/@handle</code>, <code>/channel/UC…</code>, <code>/c/…</code>, <code>/user/…</code>, optionally ending in <code>/videos</code>, <code>/shorts</code> or <code>/streams</code>), playlists, search result pages (their filters are kept) and hashtag pages (<code>/hashtag/cooking</code>).

## `maxResults` (type: `integer`):

For channels, the limit applies to each tab you choose (Videos, Shorts, Live).

## `fullDetails` (type: `boolean`):

Exact publish date and time, duration, tags and category for every row (also for search, channel and playlist results). Turn off only if you need speed over completeness: views, likes, comment count, date, description and channel data are included either way.

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

Relevance keeps the YouTube order. YouTube no longer sorts search results by date and sorts by views only roughly, so Newest first and Most viewed read the whole result list of the search (up to 1,000 videos, only the list pages) and sort it before reading the videos you keep.

## `uploadDate` (type: `string`):

Only videos uploaded in this period (YouTube filter).

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

Videos, Shorts or live streams. "Everything" returns what the YouTube page shows, Shorts shelves included.

## `duration` (type: `string`):

Video length (YouTube filter).

## `features` (type: `array`):

YouTube search features: all selected must match.

## `channelTabs` (type: `array`):

Which tabs to read from channel URLs (a URL ending in /videos, /shorts or /streams reads only that tab).

## `channelSort` (type: `string`):

Same orders as the channel page. With newest first, publishedAfter stops the scraper at the first older video.

## `publishedAfter` (type: `string`):

A date (<code>2026-09-01</code>) or an age (<code>7 days</code>, <code>2 weeks</code>, <code>3 months</code>). Works for searches, channels, playlists and videos; on channels sorted newest first the scraper stops as soon as it reaches older videos. Older videos are not charged.

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

0 = no comments. Comments are added to each video row (text, author, likes, replies, pinned, hearted by the creator) and charged per comment.

## `commentsSort` (type: `string`):

Top comments or newest first, as on YouTube.

## `country` (type: `string`):

Two-letter country code (US, GB, DE, IN, BR…): YouTube ranks search results and checks video availability for this country.

## `language` (type: `string`):

Language code for search results (en, es, de, pt, fr, hi…). Used with Relevance order; Newest first and Most viewed read the result list in English to sort it.

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

Higher is faster.

## Actor input object example

```json
{
  "searchQueries": [
    "lofi hip hop",
    "iphone 17 review"
  ],
  "startUrls": [
    {
      "url": "https://www.youtube.com/@mkbhd"
    },
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "maxResults": 20,
  "fullDetails": true,
  "sortBy": "relevance",
  "uploadDate": "any",
  "videoType": "all",
  "duration": "any",
  "features": [],
  "channelTabs": [
    "videos"
  ],
  "channelSort": "newest",
  "maxComments": 0,
  "commentsSort": "top",
  "country": "US",
  "language": "en",
  "maxConcurrency": 20
}
```

# Actor output Schema

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

One row per video, Short or stream: title, exact publish date, duration, views, likes, comment count, tags, category, hashtags, channel data and, if requested, 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 = {
    "searchQueries": [
        "lofi hip hop"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("brii3343/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": ["lofi hip hop"] }

# Run the Actor and wait for it to finish
run = client.actor("brii3343/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 '{
  "searchQueries": [
    "lofi hip hop"
  ]
}' |
apify call brii3343/youtube-scraper --silent --output-dataset

```

## MCP server setup

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