Skip to content

YouTube Scraper

Try for free

Scrape public YouTube videos, channels, playlists, hashtags, and search results. Get titles, views, likes, durations, upload dates, descriptions, and channel details.

📹 YouTube Scraper

Public YouTube videos, channels, playlists, hashtags, and search results — structured in one dataset, without the official Data API quota.

Built for research, competitive tracking, and catalog jobs that need titles, view counts, likes, comment counts, subscriber counts, descriptions, and caption tracks YouTube already publishes.

✨ Features

  • 🔎 Search terms. searchQueries returns videos, Shorts, and streams up to maxResults, maxResultsShorts, and maxResultStreams.
  • 🔗 Direct URLs. A video, Shorts, or live URL, a channel, a playlist, a hashtag page, or a YouTube search-results URL. A non-YouTube URL is rejected before the run starts. A video id YouTube does not publish is skipped.
  • ✅ Search filters YouTube already offers. sortingOrder, dateFilter, videoType, lengthFilter, and the feature checkboxes (isHD, hasSubtitles, hasCC, is3D, isLive, isBought, is4K, is360, hasLocation, isHDR, isVR180).
  • 📅 Channel windows. sortVideosBy follows Latest, Popular, or Oldest when that chip is on the channel tab. oldestPostDate keeps channel videos whose publish time is on or after that date.
  • 📝 Subtitles that already exist. transcriptionAndSubtitle set to ALWAYS_SUBTITLES when a caption track is present. Language, format (srt, vtt, xml, plaintext), and an optional key-value store copy via saveSubsToKVS.
  • ⚡ HTTP only. The run reads public pages and the same JSON those pages call. No browser.

Speech-to-text is not part of this actor. Older inputs that still send aiVideoDescription, aiVideoSummary, ALWAYS_TRANSCRIBE or TRANSCRIPTION_AS_FALLBACK keep working: the AI fields and ALWAYS_TRANSCRIBE are ignored, and TRANSCRIPTION_AS_FALLBACK behaves like ALWAYS_SUBTITLES.

🚀 Why teams use this

  • Request-based fetches, so a run spends its time on YouTube data instead of launching a browser.
  • A missing channel or playlist does not kill the run. That input is listed in the run's OUTPUT record and status message (never as a dataset row, never charged), and the rest of the run continues. A video id YouTube does not publish adds no row.
  • Counts and text are written only when the page or JSON already contains them. Missing keys stay off the item. A real 0 or false stays.
  • Same input names as a standard YouTube scrape form, so a search, a channel, or a list of URLs drops in without a new mapping layer.
  • Residential proxy is requested for the run. Sessions rotate after HTTP 429 or 401.

💡 Use cases

  • Collect videos for a search query with views, likes, and channel data.
  • Monitor a channel or playlist for new uploads.
  • Research competitors' video topics and performance.

🧪 Example input

{
  "maxResults": 10,
  "searchQueries": [
    "web scraping tutorials"
  ]
}

🧾 Sample output

One item from a real run of the example input, shortened. Long text is cut and lists show their first entries.

{
  "id": "XXXXXXXXXXX",
  "title": "Learn Web Scraping in 5 Minutes (NO PRIOR KNOWLEDGE)",
  "url": "https://www.youtube.com/watch?v=XXXXXXXXXXX",
  "type": "video",
  "viewCount": 175059,
  "date": "2026-03-05T07:01:30-08:00",
  "duration": "00:04:53",
  "thumbnailUrl": "https://i.ytimg.com/…",
  "channelName": "Example Channel",
  "channelId": "UCxxxxxxxxxxxxxxxxxxxxxx",
  "channelUsername": "examplechannel",
  "channelUrl": "https://www.youtube.com/@examplechannel",
  "likes": 6720,
  "numberOfSubscribers": 103000,
  "input": "web scraping tutorials",
  "fromYTUrl": "https://www.youtube.com/results?search_query=web+scraping+tutorials",
  "order": 1
}

📥 Input

Send searchQueries or startUrls. When startUrls is set, search terms are ignored.

FieldRole
searchQueriesSearch terms, one per line.
maxResultsRegular videos to keep per search, channel, playlist, or hashtag. Default 10. 0 skips them. A direct video URL is still returned.
maxResultsShortsShorts cap. 0 skips Shorts on listings.
maxResultStreamsStreams cap. 0 skips streams on listings.
startUrlsYouTube video, channel, playlist, hashtag, or search-results URLs. Other hosts are rejected before the run starts.
transcriptionAndSubtitleNONE or ALWAYS_SUBTITLES. ALWAYS_SUBTITLES downloads caption tracks that already exist.
subtitlesLanguageany or a language code (en, de, es, fr, it, ja, ko, nl, pt, ru).
subtitlesFormatsrt, vtt, xml, or plaintext.
sortingOrderSearch sort: relevance, rating, date, views.
dateFilterSearch upload window: hour, today, week, month, year.
videoTypevideo or movie.
lengthFilterunder4 (under 4 minutes), between420 (YouTube's 3–20 minute chip), plus20 (over 20 minutes).
isHD, hasSubtitles, hasCC, is3D, isLive, isBought, is4K, is360, hasLocation, isHDR, isVR180Search feature filters. Applied only when set to true. Live hits are streams; with maxResultStreams at 0 they count toward maxResults.
oldestPostDateChannel videos published on or after this absolute or relative date. Forces channel sort to newest.
sortVideosByNEWEST, POPULAR, or OLDEST on channel tabs.
saveSubsToKVSAlso store downloaded subtitle text in the run key-value store.
preferAutoGeneratedSubtitlesPrefer an automatic caption track when both exist.

maxResults is required. An input with no search and no URL is rejected before the run starts. A search whose video, Shorts, and stream caps are all 0 stores no rows. A direct video URL is still returned when the listing caps are 0.

📤 Output

Each success item is one public video. Fields appear only when the downloaded page contains them.

Always set when the video was read: id, url, type (video, shorts, or stream), input, order.

Typical watch-page fields: title, viewCount, date, duration, thumbnailUrl, channelName, channelUrl, channelUsername, channelId, text, descriptionLinks, hashtags, likes, commentsCount, commentsTurnedOff, numberOfSubscribers, tags, category, chapters, thumbnails, subtitleLanguages, isFamilySafe, isUnlisted, isLiveContent (plus isLiveNow, isUpcoming, liveStartTime, liveEndTime for streams and premieres), fromYTUrl.

Channel listings can also carry channelDescription, channelLocation, channelJoinedDate, channelTotalVideos, channelTotalViews, channelAvatarUrl, channelBannerUrl, and isChannelVerified when the channel header or About data includes them.

subtitles is an array of {language, type, srt} and, when saveSubsToKVS is on, srtUrl. type is user_generated or auto_generated.

location, translatedTitle, translatedText, isMembersOnly, isPaidContent, and isAgeRestricted are included only when that watch payload says so.

isMonetized, aiVideoDescription, aiVideoSummary, and transcriptionUrl are not emitted. Comment bodies are not scraped. The comment count is.

An input that gave no videos is not a dataset row. It is listed in the run's OUTPUT key-value record as failedInputs and summarised in the status message. A missing channel looks like this there:

{
  "inputUrl": "https://www.youtube.com/@this-channel-does-not-exist-xyz",
  "error": "CHANNEL_DOES_NOT_EXIST",
  "errorDescription": "HTTP 404"
}

Other error codes used here: NOT_FOUND, CHANNEL_HAS_NO_VIDEOS, CHANNEL_HAS_NO_SHORTS, CHANNEL_HAS_NO_LIVE_VIDEOS, NO_VIDEOS, NO_RESULTS, DATE_FILTER_TOO_STRICT, AGE_RESTRICTED.

💰 Pricing

Pay per event, plus platform usage (compute and residential proxy traffic):

  • Result: $0.003 per saved video, Short or stream ($3 per 1,000).
  • Date filter: $0.0008 per result when dateFilter (search) or oldestPostDate (channels) filters the results.
  • Subtitles cost no extra event. Failed inputs (missing channels, empty searches) are never charged.

Example: 1,000 videos with no date filter ≈ $3 in event fees plus about $0.56 of platform usage (measured: 100 search results used $0.056, 10 used $0.007).

Related actors

G2
4.7/5
Excellent
Trustpilot

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.