Skip to content

YouTube Scraping: Get Video Stats, Channel Data and Subtitles

YouTube scraping gets you titles, views, likes, comment counts, durations and channel stats from public channels, playlists and searches. Here is how to do it without code or with the API, using a real run on the NASA JPL channel.

Published
Reading time
8 min read
Pixel-art robot with an orange >_ on its terminal head pulls a video card with the YouTube play-button logo out of a large monitor showing the YouTube logo and loads it into a crate
In this article
  1. What data you can get from YouTube
  2. How to scrape YouTube without code
  3. How to scrape YouTube with the API
  4. curl
  5. Python
  6. JavaScript
  7. MCP for AI agents
  8. A real run: NASA channel videos, 5 videos
  9. What it costs
  10. Limits and common problems
  11. Is it legal to scrape YouTube?
  12. Alternatives
  13. FAQ
  14. Can you scrape YouTube without the API?
  15. How do I scrape all videos from a YouTube channel?
  16. Can you scrape YouTube comments?
  17. Can I download YouTube subtitles?
  18. How much does YouTube scraping cost?

YouTube scraping means collecting the public data around videos: titles, view counts, likes, comment counts, upload dates, durations, channel statistics and existing subtitles. The fastest way is a ready-made Actor: paste a channel, playlist or search, set how many videos you want, and export the rows as JSON or CSV a few seconds later.

This guide shows which fields you get, how to run the scraper without code, and how to call it from curl, Python, JavaScript or an AI agent. It also covers what it costs, where it stops, the legal side and when the official YouTube Data API is the better choice. Every number below comes from a real run on 22 October 2026 that scraped the five latest videos from NASA's Jet Propulsion Laboratory channel.

What data you can get from YouTube

Each row is one public video, Short or stream. These are the fields most people use:

Field What it holds
title Video title
url Watch URL
type video, shorts or stream
viewCount Views, as a number
likes Like count
commentsCount Number of comments (not the comment text)
date Upload time with a UTC offset, e.g. 2026-10-12T16:25:11-07:00
duration Length as HH:MM:SS
text Video description
tags, category Uploader tags and YouTube category
channelName, channelId, channelUrl The channel that posted it
numberOfSubscribers Channel subscriber count
channelTotalVideos, channelTotalViews Channel totals, on channel listings
subtitleLanguages, subtitles Caption tracks that exist, and their text when you ask for it

Fields appear only when YouTube's page contains them, and a real 0 or false is kept. Comment bodies are not scraped, and there is no speech-to-text: you get subtitles only where a caption track already exists.

How to scrape YouTube without code

  1. Open the YouTube Scraper in the Scrape.ly Store.
  2. Pick the NASA channel videos preset. It fills in this input:
json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/@NASAJPL"
    }
  ],
  "maxResults": 5,
  "maxResultsShorts": 0,
  "maxResultStreams": 0
}
  1. Swap in your own channel, playlist, video or search URL, and change the numbers.
  2. Start the run. A five-video channel run finished in about 13 seconds.
  3. Export the results as JSON, CSV or Excel.

The input fields that matter most:

  • startUrls: YouTube video, channel, playlist, hashtag or search-results URLs. Non-YouTube URLs are rejected before the run starts. When URLs are set, search terms are ignored.
  • searchQueries: search terms, typed the way you would in YouTube's search bar. Combine them with sortingOrder, dateFilter, lengthFilter and feature filters such as hasSubtitles or is4K.
  • maxResults (required): how many regular videos to keep per search, channel, playlist or hashtag. Default 10.
  • maxResultsShorts and maxResultStreams: separate caps for Shorts and streams. Both default to 0, so a channel run returns regular videos only unless you raise them.
  • transcriptionAndSubtitle: set to ALWAYS_SUBTITLES to download caption tracks that already exist, with subtitlesLanguage (default en) and subtitlesFormat (srt, vtt, xml or plaintext).

For channels, sortVideosBy follows the Latest, Popular or Oldest buttons, and oldestPostDate keeps only videos published on or after a date.

How to scrape YouTube with the API

Get your token from Settings → API & Integrations in the Scrape.ly dashboard and export it as SCRAPELY_TOKEN. The Actor API docs cover every endpoint.

curl

This run takes well under the 45-second limit of the synchronous endpoint, so one call starts the run and returns the items as a JSON array. Add ?format=csv for CSV.

shell
curl -X POST "https://api.scrape.ly/v2/actors/echofield~youtube-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls": [{"url": "https://www.youtube.com/@NASAJPL"}], "maxResults": 5, "maxResultsShorts": 0, "maxResultStreams": 0}'

Bigger jobs can take longer than 45 seconds. The call then answers 408 while the run keeps going. Don't call again, because that starts a second run. Use the asynchronous flow in the Actor API docs or one of the clients below, and read the rows with the dataset API.

Python

Install the Python client with pip install scrapely-client-python. call() waits for the run however long it takes.

python
import os
from scrapely_client import ScrapelyClient

client = ScrapelyClient(os.environ["SCRAPELY_TOKEN"], api_url="https://api.scrape.ly")

run = client.actor("echofield/youtube-scraper").call(
    run_input={
        "startUrls": [{"url": "https://www.youtube.com/@NASAJPL"}],
        "maxResults": 5,
        "maxResultsShorts": 0,
        "maxResultStreams": 0,
    }
)
print(run.status)  # SUCCEEDED, FAILED, ABORTED or TIMED-OUT
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item["title"], item.get("viewCount"), item.get("likes"))

Use item.get() for counts, since a field YouTube didn't send is left off the row.

JavaScript

Install the JavaScript client with npm install scrapely-client.

javascript
import { ScrapelyClient } from 'scrapely-client';

const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN, baseUrl: 'https://api.scrape.ly' });

const run = await client.actor('echofield/youtube-scraper').call({
  startUrls: [{ url: 'https://www.youtube.com/@NASAJPL' }],
  maxResults: 5,
  maxResultsShorts: 0,
  maxResultStreams: 0,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);

MCP for AI agents

Scrape.ly runs a hosted MCP server at https://api.scrape.ly/mcp. In Cursor, add it to ~/.cursor/mcp.json:

json
{
  "mcpServers": {
    "scrapely": {
      "url": "https://api.scrape.ly/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

In Claude Code, run claude mcp add --transport http scrapely https://api.scrape.ly/mcp, then /mcp to sign in with OAuth. The agent finds the Actor with search-actors, reads its input with fetch-actor-details, runs it with call-actor and reads rows with get-actor-output. Try a prompt like: "Use scrapely to run echofield/youtube-scraper on https://www.youtube.com/@NASAJPL for the 5 latest videos and give me a CSV of title, views, likes and upload date."

A real run: NASA channel videos, 5 videos

We ran the preset on 22 October 2026. It saved 5 videos in 12.7 seconds on 512 MB of memory and was charged $0.0185 in total. All five rows have channelName "NASA Jet Propulsion Laboratory", so that column is left out here:

title viewCount likes commentsCount date duration url
Welcome to Our Universe: Explore JPL 2026 22,219 448 30 2026-10-12T16:25:11-07:00 00:01:36 youtube.com/watch?v=VQEQ0BuHNEY
NASA’s SkyFall Mars Helicopters 296,672 4,739 446 2026-10-06T13:32:48-07:00 00:01:01 youtube.com/watch?v=DOhJpThqrxs
JPL x SpaceX \ NXT in Space: Episode 4 11,951 120 4 2026-10-01T15:36:00-07:00 00:39:24 youtube.com/watch?v=gIURQuAEec4
What's Up: October 2026 Skywatching Tips from NASA 31,840 515 40 2026-10-01T09:57:06-07:00 00:02:42 youtube.com/watch?v=0w5hBQcFYaw
JPL x Aerospace Corporation \ NXT in Space: Episode 3 12,009 90 9 2026-09-10T16:00:57-07:00 00:40:25 youtube.com/watch?v=hSFrdPXNwtw

The console shows a short, clean run:

Text
2026-10-22T15:22:59.875Z [Scrapely] Container started (setup 0.8 s)
2026-10-22T15:23:01.155Z [scrapely.actor] INFO  [Scrapely] Initializing API storage for run 219d9585d3204549b
2026-10-22T15:23:01.300Z [scrapely.proxy_configuration] INFO  Platform proxy access check succeeded.
2026-10-22T15:23:11.257Z [scrapely.actor] INFO  [Status message]: Saved 5 results.
2026-10-22T15:23:11.834Z [Scrapely] Container state: status=exited exitCode=0 oomKilled=false

The SkyFall Mars Helicopters video has 296,672 views, more than the other four combined. The two "NXT in Space" episodes run about 40 minutes, while the rest are under three. Note that date keeps YouTube's -07:00 offset, so convert to UTC before you join it with other data. The full record for the first video also carried channel data: 1,240,000 subscribers, 1,434 channel videos and isChannelVerified: true.

What it costs

The Actor charges per event:

  • Result: $0.003 per saved video, Short or stream.
  • Date filter: $0.0008 per result when dateFilter (search) or oldestPostDate (channels) is set and applied.

This run saved 5 results with no date filter, so the result fees were 5 × $0.003 = $0.015. The run was charged $0.0185 in total because platform usage was added on top: $0.0031 of residential proxy traffic and $0.0004 of compute, plus a fraction of a cent for dataset writes.

For 1,000 videos you pay $3.00 in result fees, or $3.80 if a date filter applies to every one (1,000 × $0.0038). Platform usage comes on top. Subtitles don't add an event, and failed inputs, such as a channel that doesn't exist, are never charged.

Limits and common problems

  • No comment text. You get commentsCount, not the comments. If you need the text, the official API's commentThreads.list returns it (see Alternatives).
  • Shorts and streams are off by default. maxResultsShorts and maxResultStreams default to 0. A search with all three caps at 0 stores no rows.
  • Missing inputs don't become rows. A missing channel or playlist is listed in the run's OUTPUT record as failedInputs (for example CHANNEL_DOES_NOT_EXIST) and the rest of the run continues. Check that record if a channel seems to be missing.
  • Fields can be absent. Counts and text are written only when the page has them. Code against missing keys rather than assuming every row has likes.
  • Subtitles only where they exist. ALWAYS_SUBTITLES downloads existing caption tracks. Videos without one get none, and there is no transcription.
  • Long runs and the sync endpoint. This run took 13 seconds. Big channel pulls can pass 45 seconds, so use the clients or the asynchronous flow for those.

The data in this guide is public: anyone can see it on YouTube without logging in. That does not settle the question. YouTube's Terms of Service say you may not access the service by automated means such as scrapers, except for public search engines following robots.txt or with YouTube's prior written permission. They also bar collecting information that might identify a person, such as usernames or faces, without that person's permission.

Channel names and descriptions can be personal data when the channel belongs to an individual, and then privacy laws like the GDPR and CCPA apply to how you collect, store and use them. Videos and thumbnails are also protected by copyright. This is not legal advice: if you plan to scrape YouTube for a business purpose, get advice from a lawyer for your specific case.

Alternatives

  • The YouTube Data API v3. Google's official API returns videos, channels, playlists and comment threads as structured JSON. It is metered by quota: by default 10,000 units a day for most endpoints, plus a separate bucket of 100 search.list calls a day. A videos.list or channels.list call usually costs 1 unit, invalid requests cost at least 1, and quotas reset at midnight Pacific Time (quota costs). You can apply for more. It is the better choice when you need comment text or your own channel's data, or when a sanctioned source matters more to you than volume.
  • yt-dlp. An open-source Python command-line tool for downloading audio and video. It can also print per-video metadata. It is a good fit for one-off jobs on a handful of URLs from your own machine.
  • scrapetube. A small MIT-licensed Python library for listing videos from channels, playlists and searches. Pick it if you only need video lists and will handle proxies and failures yourself.
  • A headless browser. Playwright or Puppeteer give you full control over what you read. You also own the upkeep: YouTube's page markup changes, and at volume you need your own proxies.

FAQ

Can you scrape YouTube without the API?

Yes. The scraper reads the public pages and the same JSON those pages load, so it needs no API key and has no daily quota. You pay per saved video instead ($0.003 each), plus platform usage.

How do I scrape all videos from a YouTube channel?

Put the channel URL in startUrls and raise maxResults. Set maxResultsShorts and maxResultStreams too if you want Shorts and streams. Each record's channelTotalVideos (1,434 for NASA JPL on 22 October 2026) shows how many videos the channel reports. For large pulls, use the Python or JavaScript client so you don't hit the 45-second sync limit.

Can you scrape YouTube comments?

This Actor returns the comment count (commentsCount) but not comment bodies. For the comment text itself, the YouTube Data API's commentThreads.list method returns comments at a quota cost of 1 unit per call.

Can I download YouTube subtitles?

Yes, if the video already has a caption track. Set transcriptionAndSubtitle to ALWAYS_SUBTITLES and choose the language and format. Turn on saveSubsToKVS to also save each file in the run's key-value store. Auto-generated tracks count; set preferAutoGeneratedSubtitles if you want those first.

How much does YouTube scraping cost?

$3.00 per 1,000 videos in result fees, or $3.80 with a date filter, plus platform usage. Our five-video run cost $0.0185 in total.

  • youtube
  • video data
  • python
  • api

About the author

Actor publisher on the Scrape.ly Store

Posts, reels, comments and creator stats, from TikTok and YouTube to Weibo and Bluesky. For social listening, creator research and catching a trend while it is still small. A Scrapely studio.

//Keep reading\\

The internet is full of data.
Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

No credit card. No setup calls.