YouTube Search & Video Metrics [Only $0.9💰] Scraper
Pricing
from $0.90 / 1,000 results
YouTube Search & Video Metrics [Only $0.9💰] Scraper
Scrape YouTube search results without login or API key. Metrics mode returns flat analytics rows — parsed views, duration, channel, publish age — per video, with free title/age filters (filtered videos never charged). Schedule it for keyword monitoring. JSON or CSV.
Pricing
from $0.90 / 1,000 results
Rating
5.0
(2)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
5
Bookmarked
294
Total users
82
Monthly active users
a day ago
Last modified
Categories
Share
YouTube Search & Video Metrics Scraper
Turn any YouTube search into structured video data — no login, no API key, no quota. Paste search URLs or plain keywords and get video titles, channels, view counts, durations, publish age, and thumbnails as JSON or CSV.
Metrics mode returns one flat, analytics-ready row per video (parsed views number, durationSeconds, publishedAgeDays, isLive) and skips YouTube's non-video junk (shelves, ads, channel cards) — so you only pay for actual videos. Combine with the free title and age filters and a schedule, and it becomes a keyword-monitoring pipeline.
Features
- Metrics mode: flat analytics rows — parsed view counts, duration in seconds, publish age in days, live-stream flag, originating query,
checkedAttimestamp. - Free result filters:
titleMustInclude,titleExclude, andmaxAgeDaysrun BEFORE billing — filtered videos are never charged. - Junk-row protection: shelves, ads, and the channel cards and playlist lockups YouTube mixes into a keyword search are skipped, not billed — in metrics mode, and in raw mode whenever a filter or an extra budget is set. Only the kind of result
videoTypeasks for is charged. - RUN_SUMMARY diagnostics: every run writes pages parsed, items seen, junk skipped, and per-filter drop counts — "why did I get fewer videos?" is answered by the run itself.
- Flexible input: plain keywords in
searchQueries, or full YouTube search URLs instartUrls— both work, and a pasted URL's ownsp=filter token is honoured. - YouTube's own search filters: result type (video/channel/playlist/movie), duration, upload date, sort order, HD/4K/HDR/360/3D/VR180, live, subtitles, Creative Commons, location. Applied SERVER-SIDE, so non-matching results are never fetched and never charged.
- Separate Shorts and live-stream budgets:
maxResultsShortsandmaxResultStreamscollect those kinds without eating themaxItemsvideo allowance. - Subtitle discovery: which caption languages a video has, authored vs auto-generated (see the honest limit under FAQ).
- Raw mode (default): the full YouTube renderer object per result, for consumers that want everything.
- Proxy support and concurrency control.
Metrics mode — YouTube keyword tracking
Set "metricsMode": true:
{"videoId": "1nVGaNbvuXg","url": "https://www.youtube.com/watch?v=1nVGaNbvuXg","title": "How I'd Learn Data Engineering in 2026 From Zero to Senior","channelName": "Data with Baraa","channelUrl": "https://www.youtube.com/@DataWithBaraa","views": 166861,"viewsText": "166,861 views","publishedTimeText": "5 months ago","publishedAgeDays": 150,"durationText": "32:59","durationSeconds": 1979,"isLive": false,"query": "data engineering","position": 1,"checkedAt": "2026-07-08T09:59:20.000Z"}
Typical setups:
- Keyword monitoring: schedule the same queries with
maxAgeDays: 7— each run returns only fresh uploads for your niche. - Competitor tracking: query competitor brand names, sort the dataset by
views. - Content research:
titleMustInclude/titleExcludeshape the result set before you pay for a single row.
How to Use
- Set Up: Ensure you have an Apify account and access to the Apify platform.
- Configure Input: Set the YouTube search URL(s) or keyword(s) you want to scrape results for (see Input Data section).
- (Optional) Adjust additional parameters like
maxItems, concurrency, and proxy settings. - Run the Scraper: Execute the scraper on the Apify platform.
- Data Collection: The scraper will output data in your chosen format, which can include JSON, CSV, or others as supported by Apify.
Input Configuration
Here's an example of how to set up the input for the YouTube Search Results Scraper:
{"searchQueries": ["music","medical"],"startUrls": ["https://www.youtube.com/results?search_query=drone+footage"],"maxItems": 100,"videoType": "video","lengthFilter": "plus20","dateFilter": "month","sortVideosBy": "views","is4K": true,"maxConcurrency": 10,"minConcurrency": 1,"maxRequestRetries": 10,"proxy": { "useApifyProxy": true }}
Input Fields Explanation
searchQueries: Array of plain YouTube search terms.startUrls: Array of full YouTube search URLs (keywords still accepted here too). A URL's ownsp=filter token is used unless a filter input below overrides it.maxItemsis a budget PER QUERY. Counters live in each search chain, so 10 queries withmaxItems: 100can return up to 1,000 billable rows.RUN_SUMMARY.totalBudgetreports the run's actual ceiling.videoType:any|video|channel|playlist|movie. Channel/playlist/movie searches return their own row shapes, tagged withresultTypein metrics mode (raw mode keeps YouTube's ownchannelRenderer/lockupViewModel/movieRendererwrapper as the discriminator). Result kinds this filter did not ask for are skipped as junk, never billed.lengthFilter:any|under4|between420|plus20.dateFilter:any|hour|today|week|month|year.oldestPostDate: exact cutoff, as an ISO date or a relative phrase (3 days,2 weeks). Narrows the search to the tightest matching upload-date bucket, then applies the exact cutoff per row — free, before billing.sortVideosBy:relevance|date|views|rating(NEWEST/POPULAR/OLDESTalso accepted).sortingOrder:descending(YouTube's own) |ascending. YouTube has no ascending sort, soascendingreorders what THIS RUN collected — not all of YouTube. Ondate/viewsthe rows are ordered on the parsed number; onrelevance/ratingthere is no number, so the collected order is reversed.isHD,is4K,isHDR,is360,is3D,isVR180,isLive,hasSubtitles,hasCC(Creative Commons),hasLocation,isBought: boolean quality/feature filters (default: false).maxResultsShorts: separate per-query budget for Shorts, flattened into one row each (default: 0 = off). YouTube stops serving Shorts shelves oncevideoTypeorsortVideosByis set, so those combinations collect none — the run gives up on the budget after 5 empty pages instead of paginating to the end.maxResultStreams: separate per-query budget for live streams; queues a dedicated live-filtered search per query (default: 0 = off). Ignored whenisLiveis on (every result is already a live stream, somaxItemsis the budget) or whenvideoTypeis channel/playlist/movie.transcriptionAndSubtitle:NONE|SUBTITLE_METADATA|ALWAYS_SUBTITLES(default: NONE). See the subtitles FAQ below.subtitlesLanguage,subtitlesFormat,preferAutoGeneratedSubtitles,saveSubsToKVS: subtitle selection and output options.metricsMode: Output one flat analytics row per video instead of the raw renderer object (default: false).titleMustInclude: Keep only videos whose title contains at least one of these terms — free, never charged (default: []).titleExclude: Drop videos whose title contains any of these terms — free (default: []).maxAgeDays: Drop videos older than N days; 0 disables the age filter — free (default: 0).maxItems: Maximum number of search result items to scrape (default: 100).maxConcurrency: Maximum number of pages processed simultaneously (default: 10).minConcurrency: Minimum number of pages processed simultaneously (default: 1).maxRequestRetries: Number of retries for failed requests (default: 10).proxy: Proxy configuration, used on free runs. Paid runs go through the actor's own built-in residential pool, so this input — group and country included — is not applied; the run logs a line saying so.
Output Structure
The output data includes detailed information about each search result item. The structure can vary depending on the type of result (video, playlist, channel, etc.). Here's a more comprehensive breakdown of the output structure, focusing on a playlist item:
{"radioRenderer": {"playlistId": "RDQMsHhx03c4Dwk","title": {"simpleText": "Mix - Music"},"thumbnail": {"thumbnails": [{"url": "https://i.ytimg.com/vi/859u6uiZdds/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLAEZ8uHdyBRjh16O5H9eUfB5hTotQ","width": 168,"height": 94},// ... more thumbnail sizes ...],"sampledThumbnailColor": {"red": 89,"green": 66,"blue": 53}},"videoCountText": {"runs": [{"text": "50+ videos"}]},"navigationEndpoint": {"clickTrackingParams": "CLcDELs3GAAiEwj558GAhd6IAxVIcA8CHV5aOmUyBnNlYXJjaA==","commandMetadata": {"webCommandMetadata": {"url": "/watch?v=859u6uiZdds&list=RDQMsHhx03c4Dwk&start_radio=1","webPageType": "WEB_PAGE_TYPE_WATCH","rootVe": 3832}},"watchEndpoint": {"videoId": "859u6uiZdds","playlistId": "RDQMsHhx03c4Dwk","params": "OALAAQE%3D","continuePlayback": true,"loggingContext": {"vssLoggingContext": {"serializedContextData": "Gg9SRFFNc0hoeDAzYzREd2s%3D"}}}},"videos": [{"childVideoRenderer": {"title": {"simpleText": "Tujamo - Down (Official Music Video)"},"lengthText": {"accessibility": {"accessibilityData": {"label": "3 minutes, 15 seconds"}},"simpleText": "3:15"},"videoId": "859u6uiZdds"}},// ... more videos ...],"longBylineText": {"simpleText": "C. Tangana, Öwnboss, ELYAZ, and more"},"thumbnailOverlays": [{"thumbnailOverlayBottomPanelRenderer": {"text": {"simpleText": "Mix"},"icon": {"iconType": "MIX"}}},// ... more overlays ...]}}
Field Explanations
radioRenderer: Contains information about a YouTube Mix playlist.playlistId: Unique identifier for the playlist.title: Title of the playlist.simpleText: Plain text of the title.
thumbnail: Information about the playlist's thumbnail image.thumbnails: Array of thumbnail objects with different sizes.url: URL of the thumbnail image.width: Width of the thumbnail in pixels.height: Height of the thumbnail in pixels.
sampledThumbnailColor: Average color of the thumbnail, useful for UI design.
videoCountText: Indicates the number of videos in the playlist.navigationEndpoint: Contains data for navigating to the playlist.clickTrackingParams: Used by YouTube for analytics.commandMetadata: Metadata for the navigation action.watchEndpoint: Specific data for starting playback.videoId: ID of the first video in the playlist.playlistId: ID of the playlist to be played.params: Additional parameters for playback.
videos: Array of video objects in the playlist.childVideoRenderer: Contains information about each video.title: Title of the video.lengthText: Duration of the video.accessibility: Accessible version of the duration.simpleText: Formatted duration string.
videoId: Unique identifier for the video.
longBylineText: Description of the playlist content, often listing featured artists.thumbnailOverlays: Array of overlay information displayed on the thumbnail.thumbnailOverlayBottomPanelRenderer: Information for the bottom panel overlay.text: Text displayed in the overlay.icon: Icon type used in the overlay.
This structure provides a comprehensive view of a playlist item in YouTube search results. It includes details about the playlist itself, its thumbnail, navigation data, and information about the videos contained within the playlist. The actual output may include additional fields or vary slightly depending on the specific type of search result (e.g., individual videos, channels, or other content types).
Support
- For issues or feature requests, please use the Issues section of this actor.
- If you need customization or have questions, feel free to contact the author:
- Author's website: https://muhamed-didovic.github.io/
- Email: muhamed.didovic@gmail.com
Additional Services
- Request customization or whole dataset: muhamed.didovic@gmail.com
- If you need anything else scraped, or this actor customized, email: muhamed.didovic@gmail.com
- For API services of this scraper (no Apify fee, just usage fee for the API), contact: muhamed.didovic@gmail.com
FAQ
Do I need a YouTube API key or account?
No. The actor reads YouTube's public search surface — no login, no API key, no Google quota.
What's the difference between metrics mode and the default output?
Default output is YouTube's raw renderer object per result — every field YouTube sends, for developers who want it all. Metrics mode outputs one flat row per video with parsed numbers (views, duration in seconds, publish age in days) — for spreadsheets, dashboards, and scheduled keyword tracking. Both modes skip junk (shelves, ads, and the channel cards and playlist lockups mixed into a keyword search) as soon as any filter or budget is in play, so you only pay for the kind of result videoType asked for.
Are the filters really free?
Yes, in two different ways. titleMustInclude, titleExclude, maxAgeDays and oldestPostDate run before rows are saved, so filtered videos are never charged. The YouTube filters (videoType, lengthFilter, dateFilter, is4K, isLive, …) are stronger still: they are applied by YouTube itself, so non-matching results are never even fetched.
Why did I get fewer videos than maxItems?
Check the RUN_SUMMARY record in the run's key-value store — it reports pages parsed, items seen, junk skipped, per-filter drop counts, the exact spToken sent, and a stopReason. A stopReason of no-results-for-filters means YouTube genuinely had nothing for that filter combination — sharp ones (4K + HDR + last hour) legitimately return zero. rowsSaved is the run total; videosSaved, shortsSaved and streamsSaved split it by budget and no longer overlap.
Does maxItems cap the whole run?
No — it is a budget per search query. Each query runs as its own chain with its own counter, so 10 queries with maxItems: 100 can produce up to 1,000 rows. maxResultsShorts and maxResultStreams are separate per-query budgets on top of that. RUN_SUMMARY.totalBudget reports the resulting ceiling for the run.
Can it download subtitles/transcripts?
It reliably returns subtitle availability — subtitleLanguages, hasSubtitles, hasAutoGeneratedSubtitles, and which track was selected. Subtitle text is a different story: YouTube now gates the signed caption URL behind a proof-of-origin token, and it answers 200 with an empty body for every format from a cookieless HTTP client. When that happens the row says subtitlesStatus: "unavailable_requires_pot" rather than pretending the video has no captions. If you need to restrict a run to caption-bearing videos, use the hasSubtitles search filter — that works today and costs nothing extra.
Why is sortingOrder: ascending not giving me YouTube's oldest videos?
Because YouTube's search has no ascending sort — every server-side order is newest/most-viewed first. ascending reorders the set this run actually collected, so maxItems: 100 gives you the newest 100 shown oldest-first, not the 100 oldest videos on the platform. With sortVideosBy set to date or views the rows are ordered on the parsed number that was captured with each row; on relevance/rating there is nothing to order on, so the collected order is reversed. Rows are held in memory until the crawl ends (capped at 5,000 rows or ~32 MB, past which the run streams normally), so an aborted or migrated run loses the buffer.
How accurate is publishedAgeDays?
It's derived from YouTube's relative label ("3 weeks ago"), so it's approximate — precise enough for freshness filtering, not for exact timestamps.
🤖 For AI Agents & LLM Apps
Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/youtube-search-results-scraper).
Purpose: Scrape YouTube search results into structured video rows (title, channel, views, duration, publish age), with an optional flat metrics mode that skips non-video junk — no login, API key, or quota.
Minimal input:
{ "startUrls": ["music"], "maxItems": 25 }
URL variant (same field): "startUrls": ["https://www.youtube.com/results?search_query=medical"].
Output (metrics mode): one row per video — videoId, url, title, channelName, channelUrl, views, viewsText, publishedTimeText, publishedAgeDays, durationText, durationSeconds, isLive, query, position, checkedAt. Default mode returns YouTube's raw renderer object per result instead.
Behaviors an agent should know:
- Always set
maxItems(default 100); an uncapped run follows all search-result pages for every query. startUrlsaccepts both YouTube search URLs and plain keywords in the same array.- Set
metricsMode: truefor flat analytics rows carryingresultType; default output is the raw renderer object. Junk (shelves, ads, channel cards) is skipped and never billed in either mode once a filter or budget is set. - Free filters
titleMustInclude,titleExclude,maxAgeDaysrun before billing — dropped videos are never charged. - Pay-per-event billing — see the Pricing tab on the actor page.
⚠️ Disclaimer
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by YouTube or Google LLC or any of their subsidiaries. All trademarks mentioned are the property of their respective owners.
The scraper accesses only publicly available YouTube search pages — no authenticated endpoints, paid features, or content behind a login. Users are responsible for ensuring their use complies with YouTube's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.
SEO Keywords
youtube search scraper, youtube scraper, scrape youtube search results, youtube video metrics, youtube keyword tracker, youtube analytics data, youtube view count scraper, youtube trends data, youtube API alternative, youtube data extraction, video research tool, content research scraper, competitor youtube analysis, youtube monitoring tool, youtube search API, Apify youtube, video marketing data, youtube channel data, keyword research youtube, fresh video alerts