YouTube Search Scraper - Keyword Rankings avatar

YouTube Search Scraper - Keyword Rankings

Pricing

from $2.00 / 1,000 results

Go to Apify Store
YouTube Search Scraper - Keyword Rankings

YouTube Search Scraper - Keyword Rankings

Give it keywords, get YouTube's ranked results: position, title, channel, views and publish date for every result. Built for rank tracking and competitor research. No transcripts or comment text: the Video Scraper does those.

Pricing

from $2.00 / 1,000 results

Rating

0.0

(0)

Developer

Tubelens

Tubelens

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

YouTube search scraper - track keyword rankings and search results

Give it keywords, get YouTube's ranked results. Each row is one result with its position, so you always know what rank a video, channel or playlist holds for that search right now.

$0.005 per run start plus $0.002 per result, that's $2 per 1,000 results.

Takes a list of keywords, not just one, so you can track a whole set in a single run.

Why this scraper?

  • 🔑 No quota wall. YouTube's own Data API charges 100 units per search against a 10,000-unit daily default, about 100 searches a day, and requests to raise that limit for competitive analytics are frequently turned down.
  • 📋 Bulk keywords, not one at a time. Paste a list and every row carries the keyword that produced it. The dedicated search actor in this niche takes a single query string, so bulk sets are impossible there.
  • 🥇 Real rank position. Every result carries its 1-based position, counting only what a person would actually scroll past. It works in all five result types: videos rank against videos, channels against channels, playlists against playlists, Shorts against Shorts. Shelves and other page furniture never take a number.
  • 🕳️ Deep paging, not just the first screen. Around 300 to 500 unique results for a specific keyword, well past where cheaper scrapers stop. Very broad one-word terms exhaust much sooner.
  • 🎯 Filters that are honest about what works. Sort is Relevance or Popularity because those are the only two that actually reorder anything on YouTube's own page; upload window, duration and content filters all measurably change what comes back.
  • 🌍 Language genuinely changes the results. Set it to match your audience and get a different ranked list, not just relabeled text. View counts and publish dates come back as real numbers and real dates in 14 languages, Indian lakh grouping and Arabic word-counts included, not just in English.
  • 🚫 No proxy setup, no browser to babysit. Datacenter routing by default, works out of the box.
  • 🧾 Honest dates. A search result only ever carries relative text like "6 years ago", never an exact timestamp, so this actor gives you that text plus a derived date flagged as approximate instead of pretending to know the real one.

What data can you extract?

FieldTypeDescription
position, keyword, rowTypenumber, string, stringRank for this keyword, the keyword that produced the row, and the kind of row: video, channel, playlist or shelfItem
title, url, videoIdstringResult title, canonical link, and video ID when the row is a video
channel.name, channel.id, channel.url, channelHandle, channelIsVerifiedstring, string, string, string, booleanThe channel behind the result, its @handle, and its verified badge
subscriberCount, subscriberCountTextnumber, stringSubscriber count, populated on channel rows
viewCount, viewCountText, concurrentViewersnumber, string, numberLifetime view count and its text, plus a live stream's current watcher count kept in its own field, never folded into viewCount
publishedText, publishedAt, publishedAtIsApproximatestring, date, booleanThe relative text YouTube shows, a date derived from it, and a flag marking that date as approximate. The text is kept word for word in whatever language you ran
durationSeconds, durationText, isShortnumber, string, booleanLength in seconds, the text as shown, and whether the result is a Short
isLive, isUpcomingbooleanWhether the result is live now, or an upcoming premiere or scheduled stream
descriptionSnippetstringThe description preview shown under the result
badgesarrayLabels YouTube attaches, such as Live now or New
thumbnailsarrayThumbnail image URLs
playlistId, playlistItemCountstring, numberPopulated on playlist rows
shelfTitlestringNames the shelf a shelfItem row came from
estimatedResultsnumberYouTube's own total-match count for the keyword, a free signal for how competitive it is
searchedAt, languagedate, stringWhen the search ran and which language it ran in, so rows from different runs stay comparable in one table

YouTube search scraper vs the official YouTube Data API

ConcernOfficial YouTube Data APIThis actor
Daily limit10,000 units a day by default; one keyword search costs 100 units, about 100 searches a dayNo daily cap
Bulk keyword listsOne query per call, quota burns fastPaste a full keyword list in one run
Getting more quotaExtension requests for scraping or competitive analytics are frequently rejectedNothing to request
Rank positionNot returnedEvery row carries its position (shelf rows, if you enable them, don't)
SetupGoogle Cloud project, API key, OAuth on some endpointsAn Apify token, nothing else
Cost at volumeFree until quota, then blocked$2 per 1,000 results

If you need a handful of searches a day, the official API is free and fine. Past that, the quota is the wall this actor exists to remove.

How to scrape YouTube search results: step by step

  1. Create a free Apify account. Takes 30 seconds, no card needed.
  2. Open YouTube Search Scraper in the Apify Console.
  3. Paste your keywords, one per line, and set any filters you want: result type, sort, upload window, duration, features.
  4. Click Start.
  5. Export as JSON, CSV or Excel, or pull the dataset over the Apify API.

Or drive it from the command line:

curl -X POST "https://api.apify.com/v2/acts/tubelens~youtube-search-scraper/run-sync-get-dataset-items?token=APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords": ["ai agents", "cooking recipes"]}'

How much does YouTube Search Scraper cost?

Two charges: $0.005 per run start, plus $0.002 per result, which works out to $2 per 1,000 results. Every row costs the same, whatever type it is. On the Apify free plan ($5 of monthly credit) that's about 2,500 results. On Starter ($29), about 14,500.

Input

{
"keywords": ["ai agents", "cooking recipes", "react tutorial"],
"maxResultsPerKeyword": 50,
"resultType": "video",
"sortBy": "relevance",
"uploadedWithin": "any",
"duration": "any",
"features": [],
"language": "en",
"includeShelves": false
}
FieldTypeDefaultNotes
keywordsstring[]requiredOne search term per line; every result row carries the keyword that produced it
maxResultsPerKeywordinteger50Caps rows returned per keyword, not how much the actor scans, 1 to 1,000
resultTypeenumvideovideo, channel, playlist, movie, shorts
sortByenumrelevancerelevance or popularity, the only two sorts that actually work on YouTube's page
uploadedWithinenumanyany, today, week, month, year
durationenumanyany, short (under 3 min), medium (3 to 20 min), long (over 20 min)
featuresstring[][]subtitles, 4k, 360, vr180, live
languagestringenTwo-letter code; genuinely changes which results come back, not just labels. Publish dates are read in ar, de, en, es, fr, hi, id, it, ja, ko, nl, pt, ru and tr
includeShelvesbooleanfalseOff by default so you get only the organic, ranked results: anything YouTube mixes into the page without a rank, such as a shelf, a channel card or a catalogue film, is not returned and not billed. On, all of it comes back unranked and billed, and a video sitting in both the ranked list and a shelf comes back twice

Output

One row per search result, in rank order. A video row:

{
"rowType": "video",
"videoId": "UyoVmQLekBc",
"url": "https://www.youtube.com/watch?v=UyoVmQLekBc",
"title": "How I Built an AI Agent in 14 minutes as A Beginner (2026)",
"channel": {
"name": "Mikey No Code",
"id": "UCde0vB0fTwC8AT3sJofFV0w",
"url": "https://www.youtube.com/@mikeynocode"
},
"viewCount": 19861,
"viewCountText": "19,861 views",
"concurrentViewers": null,
"publishedText": "1 day ago",
"publishedAt": "2026-07-27T00:00:00.000Z",
"publishedAtIsApproximate": true,
"durationSeconds": 1082,
"durationText": "18:02",
"thumbnails": [{ "url": "https://i.ytimg.com/vi/UyoVmQLekBc/hq720.jpg", "width": 720, "height": 404 }],
"badges": ["New"],
"isShort": false,
"isLive": false,
"isUpcoming": false,
"descriptionSnippet": "Claim your FREE $499 Masterclass: Build & Sell Apps, AI Agents & Websites with AI ...",
"channelHandle": null,
"subscriberCount": null,
"subscriberCountText": null,
"playlistId": null,
"playlistItemCount": null,
"shelfTitle": null,
"channelIsVerified": true,
"position": 1,
"keyword": "ai agents",
"estimatedResults": 2411581,
"searchedAt": "2026-07-28T20:27:15.782Z",
"language": "en"
}

Fields that only apply to another row type come back null: playlistId and playlistItemCount populate on playlist rows, channelHandle, subscriberCount and subscriberCountText populate on channel rows, and shelfTitle names the shelf or Shorts grid a row sat in. concurrentViewers is deliberately separate from viewCount: a live stream's current watcher count is not a lifetime view count, so live rows populate one and not the other.

With includeShelves off, every row you get is a ranked result, so position is never null. Turn shelves on and you also get everything YouTube mixed into the page without a rank: rowType: "shelfItem" rows from a shelf, a channel card injected between two videos, and catalogue films from YouTube Movies. All of those come back with position: null, and all of them are billed. Two things to budget for: a video can sit in both the ranked list and a shelf, and you get it twice, once ranked and once as a shelfItem (measured on one 60-row run, 3 videos arrived twice), and the catalogue films carry no view count and no publish date. Dedupe on videoId if you only want one copy, and keep the row whose position is not null.

Movie searches return full films alongside ordinary long videos, all with rowType: "video". Films carry no view count and no publish date anywhere in YouTube's search response, so those two fields come back null on them rather than guessed.

Which tubelens scraper do I need?

I want to...Use
Search YouTube by keyword and get ranked results with positionThis actor, youtube-search-scraper
Pull everything from one channel: videos, Shorts, live streams, playlists, community postsyoutube-channel-scraper
Get one video's full metadata, transcript, comments and channel datayoutube-video-scraper

They chain: search finds it, the channel scraper catalogs it, the video scraper reads it.

Use cases

  • 📊 Rank tracking: monitor where a video or channel sits for target keywords over time, on a schedule.
  • 🔍 Competitive research: see which competitors' videos outrank yours for the same searches.
  • 🧭 Content gap analysis: sweep a batch of keywords and compare estimatedResults across them to spot under-served searches.
  • 📈 Title and thumbnail testing: check whether a change actually moves position.
  • 🌍 Localized research: run the same keyword in different languages and see how the ranking shifts.
  • 🥇 Agency reporting: pull rank data across many keywords for many clients into your own warehouse instead of a per-creator dashboard tool.
  • 🎬 Shorts strategy: filter to Shorts only and see what's currently ranking in that format.

Limitations

  • Depth depends mostly on the keyword, and it is not a fixed number. Runs capped at 1,000 results, measured on the live actor: "how to tie a tie" reached 505 unique results, "best laptop 2026" 459, "ai agents" 443, "yoga for beginners" 318, and the very broad "music" exhausted at 93. Specific, multi-word keywords go deep; single broad terms run out fast, because YouTube itself stops serving more. The same keyword also varies run to run: two walks of "salesforce" returned 316 and 273. Filtering to resultType: video reaches deeper than an unfiltered search. When a run stops early for any reason other than running out of results, the status message says so.
  • Publish dates are approximate. Search results carry no absolute timestamp, only text like "6 years ago". publishedAt is derived from that text and flagged with publishedAtIsApproximate: true.
  • Sort is Relevance or Popularity only. Sorting by upload date or rating doesn't actually reorder anything on YouTube's own search page, so those options aren't offered. Use the uploadedWithin filter for recency instead.
  • One result type per run. Set resultType to video, channel, playlist, movie or Shorts. YouTube does slip other shapes into a filtered page, a channel card or a catalogue film in the middle of a video search, and those are dropped rather than mixed into your rows, so a run returns the one type you asked for.
  • Only ranked results are returned and billed. position runs 1, 2, 3 and so on down the results YouTube ranked for your search, whichever result type you asked for. Anything the page carries without a rank never takes a number away from a real result: by default it isn't returned at all, and it only arrives, unranked and billed, if you turn includeShelves on.
  • A duration: short search can include rows with no length. Live streams have no fixed length, but YouTube's own filter still admits them into that bucket, so those rows report durationSeconds: null rather than a guess.
  • Country routing isn't offered. Tested and dropped: result overlap between the datacenter default, country: US and country: DE measured 48 to 70 percent, but a same-settings datacenter run repeated against itself overlapped only 64 percent, so the country effect was indistinguishable from ordinary run-to-run noise, even with residential proxy genuinely engaged. language is what actually re-ranks results, so that's the lever this actor exposes.
  • A run that stops early says Partial: and names the cause. Stopping early means something cut the run short: the time budget, a charge limit, a page ceiling, or YouTube handing back a page that couldn't be read. Asking for more results than a keyword actually has is not stopping early; that run simply returns everything that exists and reports the count plainly.
  • Publish dates need a language this actor can read. publishedAt is derived from YouTube's relative wording, which is written in the language you run in. It is read in ar, de, en, es, fr, hi, id, it, ja, ko, nl, pt, ru and tr. Run in any other language and every other field still arrives, publishedText still carries YouTube's own wording, and the run warns in its log that publishedAt will be empty rather than leaving you to find out from the data.
  • This actor doesn't read the videos it finds. Transcripts, comments and full descriptions come from youtube-video-scraper. A channel's full catalog comes from youtube-channel-scraper.

FAQ

How much does YouTube Search Scraper cost? YouTube Search Scraper uses pay-per-result pricing. You pay $2 for 1,000 results, plus a small $0.005 run-start fee. The Apify Free plan gives you $5 in usage credits a month, enough for around 2,500 results. If you run regularly, the $29/month Starter plan covers about 14,500 results.

No subscription lock-in. Pause whenever.

How deep does search go? Deeper than the first page, but it isn't unlimited, and how deep depends mostly on the keyword. Measured on the live actor with the cap at 1,000: "how to tie a tie" reached 505 unique results, "best laptop 2026" 459, "ai agents" 443, "yoga for beginners" 318, and the very broad "music" ran out at 93. Specific multi-word keywords go deep, single broad terms exhaust fast. The same keyword varies between runs too: two walks of "salesforce" returned 316 and 273. Filtering to resultType: video reaches deeper than a broad, unfiltered search.

Is it legal to scrape YouTube? Scraping public data is generally allowed in the US and most of the EU, as long as you don't collect personal data covered by GDPR or CCPA without a lawful basis. This actor only touches YouTube's public search results, but how you use the output is on you.

Apify's full breakdown: Is web scraping legal?.

Can I integrate YouTube Search Scraper with other tools? Push results into Make, Zapier, Slack, Airbyte, GitHub, Google Sheets, Google Drive, and more. Apify treats every actor as a webhook source, so anything that consumes webhooks or pulls from an API works.

Full list: Apify integrations.

Can I use YouTube Search Scraper with the Apify API? Yes. Every run is available over the Apify REST API:

curl -X POST "https://api.apify.com/v2/acts/tubelens~youtube-search-scraper/runs?token=APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords": ["ai agents"]}'

Docs: Apify API reference.

Can I use YouTube Search Scraper through an MCP Server? Yes. Apify ships an MCP server that exposes every actor as a tool, so Claude Desktop, Cursor, and any other MCP-capable client can call YouTube Search Scraper. Setup: Apify MCP docs.

Your feedback Found a bug or need a field that isn't here? Open an issue at console.apify.com/actors/ge5BpC9ZGa5R3Thh9/issues and it goes straight to a human.