YouTube Channel Scraper with Keyword Search
Pricing
from $5.99 / 1,000 results
YouTube Channel Scraper with Keyword Search
Automate YouTube channel data collection in minutes. The YouTube Channel Scraper pulls video lists, engagement metrics, timestamps, and channel info. Perfect for SEO research, content tracking, trend analysis, and scalable data pipelines.
Pricing
from $5.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
5
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
YouTube Channel Scraper — Search & Scrape Channels by Keyword
Find YouTube channels by keyword instead of by URL, then scrape every one of them across five surfaces in a single run: channel profile and About data, long-form videos, Shorts, live and past streams, and community posts. Every response is structured JSON — one row per item, ready to pass directly to an LLM, load into a spreadsheet, or feed a monitoring pipeline. Give it a search term like "home workout" or "ai news", a subscriber floor, and how deep to go per channel, and it handles the searching, filtering, and scraping itself.
🔎 What is the YouTube Channel Scraper (Channel Search)?
This Actor turns a keyword into a list of matching YouTube channels, then runs a full channel scrape on each one — channel profile, uploads, Shorts, live/past streams, and community posts — without you ever having to look up a channel URL first. Channel links, @handles, or UC… IDs can be supplied directly too, next to or instead of keywords, so a discovery run and a known-channel run can share one job. No YouTube account or login is required — everything scraped is public, logged-out data.
What sets keyword discovery apart from just pasting a URL is the provenance it keeps: every channel found by a search term carries the query, its rank in that search, and (if several keywords found the same channel) every keyword that matched it. That trail travels down to every video, Short, stream, and post row the channel produces, so a single row can always be traced back to the search that surfaced its channel.
- 🔎 Channel search by keyword —
searchQueriesruns YouTube's own channel search and pages through the results - 👥 Subscriber floor —
minSubscribersdrops discovered channels below a threshold before they're ever scraped - 🏠 Channel profile & About data — description, join date, location, lifetime views, verification badge
- 🎬 Long-form videos, 📱 Shorts, 🔴 live/past streams — each its own tab, each its own row type
- 💬 Community posts — text, image, poll, and video attachments
- 🌍 Query controls — search market (
searchMarket), search order (searchSortBy), and Videos-tab sort order (sortOrderVideos)
📊 What data can you get with the YouTube Channel Scraper?
Five row types come out of a run, each identified by a stable rowType:
| Result type | Extracted fields | Primary use case |
|---|---|---|
channel | channelDescription, channelJoinedDate, channelLocation, channelTotalVideos, channelTotalViews, isChannelVerified, availableTabs, plus the discovery record | Creator profiling, outreach lists, subscriber tracking |
video | videoId, title, url, duration, viewCount, likesCount, publishedAt | Content-gap analysis, upload-cadence tracking |
short | Same fields as video | Shorts strategy and format research |
livestream | Video fields plus isLive, isUpcoming, concurrentViewersText | Live-schedule and stream-performance tracking |
post | postId, postType, textContent, imageUrls, pollOptions, attachedVideoId, likesCount | Community-engagement and announcement monitoring |
Keyword-driven channel discovery
Every channel found through searchQueries carries a full discovery record on its channel row: which keyword found it, its rank in that keyword's result list, the search page it came from, every keyword that matched it (discoveryFoundByQueries), the market the search ran in, and the raw fields YouTube's search response returned — title, handle, subscriber label, description snippet, avatar, verification badge. This is the one thing a plain "paste a channel URL" scraper cannot give you, because there is no channel URL yet when the run starts — only a keyword.
{"rowType": "channel","channelName": "GetFit Studio","discoverySource": "keyword","discoveryQuery": "home workout","discoveryRank": 3,"discoveryPage": 1,"discoveryFoundByQueries": ["home workout", "bodyweight fitness"],"discoverySubscriberText": "2.81M subscribers","discoverySubscriberCountApprox": 2810000,"discoveryMarket": "en-US"}
Community posts
post rows cover text, image, poll, and video/playlist-attachment posts from the Community tab, each with postType, textContent, likesCount, likesCountText, and commentsCountText. Poll posts also carry pollOptions and pollTotalVotesText; video/playlist shares carry attachedVideoId. Channels with no Community tab return zero post rows rather than a guessed or empty placeholder row.
🆚 How does this Actor differ from the official YouTube Data API?
The YouTube Data API v3 is Google's public, official interface to YouTube, and it does cover channel search (search.list), channel metadata (channels.list), and video statistics (videos.list). It does not, as of the current resource list on developers.google.com (checked 2026-08-04), expose Community-tab posts at all — there is no resource for them in the official API.
| Feature | YouTube Data API v3 | This Actor |
|---|---|---|
| Community posts | Not available — no API resource for the Community tab | Returned as post rows |
| Setup | Google Cloud project + API key (OAuth for some resources) | Runs from the Apify Console; no API key or Google account |
| Daily quota | Default 10,000 units/day; a search.list call costs 100 units — about 100 keyword searches/day — per Google's quota documentation (checked 2026-08-04) | No Google quota; usage is metered by Apify instead |
| Channel discovery | search.list, one HTTP call per page of results | searchQueries, with automatic pagination up to your maxChannelsPerQuery/maxChannels limits |
| Exact view/like counts | videos.list returns them directly | deepItemDetails returns them at one extra request per item |
| Output shape | Separate JSON per resource; a full channel profile needs several calls | One normalized JSON row per item, all five surfaces in one dataset |
The official API is the right choice for an application that needs a small, quota-tracked, Google-ToS-compliant volume of channel or video lookups. This Actor is the better fit for ad hoc or repeated bulk discovery and research jobs — especially ones that need community posts, which the official API cannot supply at any quota.
🧭 How to scrape YouTube channels with this Actor
- Open the Actor's page in the Apify Console and click Start.
- Enter your search terms in Keywords to find channels (
searchQueries) — one per line — or paste known channel links,@handles, orUC…IDs into YouTube channels (startUrls). - Set the query controls that matter to your search: a Subscriber floor (
minSubscribers), a Search market (searchMarket), and a Channel search order (searchSortBy). - Choose how deep to go per channel — toggle Channel profile & About, Long-form videos, Shorts, Live & past streams, and Community posts, and set Items per section, per channel (
maxResults). - Click Start to run, then export the dataset as JSON, CSV, Excel, or any other format the Apify Console offers.
How to run multiple queries in one job
searchQueries is an array — add one keyword per line and the Actor discovers channels for each one in a single run, de-duplicating channels found by more than one keyword (their discoveryFoundByQueries lists every keyword that matched). startUrls can hold as many channel links as you like in the same run, and they're scraped alongside the keyword results without counting against maxChannels.
⬇️ Input
None of the 17 input fields are required — leave everything blank and the Actor uses its defaults, provided you supply at least one keyword or channel link (an empty run with neither raises an error naming what's missing).
| Parameter | Required | Type | Description |
|---|---|---|---|
searchQueries | No | array | Search terms, one per line. Default []. Leave empty to scrape only startUrls. |
maxChannelsPerQuery | No | integer | Channels to keep per keyword. Default 5, min 1, max 500. |
maxChannels | No | integer | Hard cap on total channels discovered across all keywords. Default 10, min 1, max 1000. Channels in startUrls don't count against it. |
minSubscribers | No | integer | Drop discovered channels below this subscriber count. Default 0, min 0, max 1000000000. |
searchSortBy | No | string (enum) | relevance (default, YouTube's default match order) or viewCount (biggest channels first). |
searchMarket | No | string | Language-COUNTRY the search runs in, e.g. en-US, de-DE, pt-BR. Default en-US. Channel pages themselves are always fetched in English. |
discoveryOnly | No | boolean | Emit one channel row per discovered channel straight from the search response and fetch nothing else. Default false. |
deepItemDetails | No | boolean | Open each video/Short/stream through YouTube's player endpoint for exact viewCount, likesCount, and publishedAt. Default true. Costs one extra request per item. |
startUrls | No | array | Channel URLs (https://www.youtube.com/@Handle or .../channel/UC…), bare @handles, or bare UC… IDs, one per line. Default []. |
maxResults | No | integer | Items per enabled section (videos, Shorts, streams, posts), per channel. Default 10, min 1, max 1000. |
sortOrderVideos | No | string (enum) | date (default, newest first), viewCount (most viewed first), or oldest (first uploads first). |
scrapeChannelInfo | No | boolean | Emit channel rows. Default true. |
scrapeVideos | No | boolean | Emit video rows from the Videos tab. Default true. |
scrapeShorts | No | boolean | Emit short rows. Default true. |
scrapeLiveStreams | No | boolean | Emit livestream rows from the Live tab. Default true. |
scrapePosts | No | boolean | Emit post rows from the Community tab. Default true. |
proxyConfiguration | No | object | Apify Proxy settings, attached to every request. Default {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US"}. |
{"searchQueries": ["home workout", "kettlebell training"],"maxChannelsPerQuery": 10,"maxChannels": 15,"minSubscribers": 1000000,"searchSortBy": "relevance","searchMarket": "en-US","discoveryOnly": false,"deepItemDetails": true,"startUrls": ["https://www.youtube.com/@MrBeast"],"maxResults": 10,"sortOrderVideos": "date","scrapeChannelInfo": true,"scrapeVideos": true,"scrapeShorts": true,"scrapeLiveStreams": true,"scrapePosts": true,"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US" }}
⚠️ minSubscribers only parses English subscriber labels. YouTube publishes a rounded label such as "9.06M subscribers"; that's the only format this Actor's parser reads. If searchMarket is set to a non-English locale and a subscriber floor is active, every channel whose label comes back localized is dropped as unreadable rather than mis-parsed — the run log counts those separately from channels that genuinely fell below the floor. Set minSubscribers to 0 if you need a non-English market without losing channels to this.
⚠️ Keyword discovery pages up to 25 search-result pages per keyword internally (roughly 20 channels per page), a limit that is not exposed as an input. maxChannelsPerQuery's own maximum of 500 sits right at that ceiling, so raising it further will not surface more channels for a single keyword — split the search into more specific keywords instead.
⬆️ Output
Every run produces one Apify dataset with typed, normalized JSON rows and a consistent schema across runs — the same keys appear on every row of a given rowType, null where a field isn't available rather than omitted. Export it from the Apify Console as JSON, CSV, Excel, XML, or HTML, or pull it with the API/SDK.
Scraped results
Every row carries rowType, channelId, channelName, channelUsername, channelUrl, numberOfSubscribers, inputUrl, scrapedAt, order, title, url, viewCount, viewCountText, publishedTimeText, and the discovery-provenance columns discoverySource, discoveryQuery, discoveryRank, discoveryPage.
channel rows additionally carry channelDescription, channelJoinedDate, channelLocation, channelAvatarUrl, channelBannerUrl, channelDescriptionLinks, channelTotalVideos, channelTotalVideosText, channelTotalViews, isChannelVerified, availableTabs, and the full discovery record: discoveryFoundByQueries, discoveryChannelId, discoveryHandle, discoveryTitle, discoverySubscriberText, discoverySubscriberCountApprox, discoveryDescriptionSnippet, discoveryThumbnailUrl, discoveryIsVerified, discoveryMarket, discoveryCountry, discoveryLanguage, discoverySortBy. On a channel row, viewCountText is repurposed to carry the channel's lifetime view count text, not a per-video figure.
video, short, and livestream rows additionally carry videoId, duration, thumbnailUrl, likesCount, publishedAt. livestream rows also carry isLive, isUpcoming, concurrentViewersText.
post rows additionally carry postId, postType (text / image / poll / video / playlist / shared), textContent, imageUrls, pollOptions, pollTotalVotesText, attachedVideoId, likesCount, likesCountText, commentsCountText.
[{"rowType": "channel","channelId": "UCa_JUG9hl8D7S6jH7nWTURA","channelName": "GetFit Studio","channelUsername": "@getfitstudio","channelUrl": "https://www.youtube.com/@getfitstudio","numberOfSubscribers": "2.81M subscribers","channelDescription": "Home workouts for every fitness level.","channelJoinedDate": "May 21, 2019","channelLocation": "Australia","channelTotalVideos": 929,"channelTotalViews": 404183563,"isChannelVerified": true,"availableTabs": ["Home", "Videos", "Shorts", "Playlists", "Posts"],"discoverySource": "keyword","discoveryQuery": "home workout","discoveryRank": 3,"discoveryPage": 1,"scrapedAt": "2026-08-04T09:12:04+00:00"},{"rowType": "video","order": 1,"channelId": "UCa_JUG9hl8D7S6jH7nWTURA","channelName": "GetFit Studio","videoId": "g3_nLhSxFHE","title": "10 Min Full-Body Home Workout - No Equipment","url": "https://www.youtube.com/watch?v=g3_nLhSxFHE","duration": "10:36","viewCount": 594231,"viewCountText": "594K views","likesCount": 15420,"publishedTimeText": "3 days ago","publishedAt": "2026-08-01T08:34:22+00:00","discoveryQuery": "home workout","discoveryRank": 3,"scrapedAt": "2026-08-04T09:12:11+00:00"},{"rowType": "short","order": 1,"channelId": "UCa_JUG9hl8D7S6jH7nWTURA","channelName": "GetFit Studio","videoId": "b7Yq2FghT0","title": "30-second ab burner","url": "https://www.youtube.com/shorts/b7Yq2FghT0","duration": "0:31","viewCount": 1203400,"viewCountText": "1.2M views","publishedTimeText": "1 week ago","scrapedAt": "2026-08-04T09:12:22+00:00"},{"rowType": "post","order": 1,"channelId": "UCa_JUG9hl8D7S6jH7nWTURA","channelName": "GetFit Studio","postId": "UgkxAbCdEfGhIjKl","postType": "poll","title": "What should next week's program focus on?","url": "https://www.youtube.com/post/UgkxAbCdEfGhIjKl","pollOptions": ["Upper body", "Core", "Mobility"],"pollTotalVotesText": "4.2K votes","likesCount": 812,"commentsCountText": "96 comments","publishedTimeText": "2 days ago","scrapedAt": "2026-08-04T09:12:30+00:00"}]
💡 How can I use the data extracted with this Actor?
- 🎯 Creator outreach and influencer discovery teams: run a keyword against your niche, filter by
minSubscribers, and build a shortlist fromchannelName,channelUsername,numberOfSubscribers, andchannelDescriptionLinkswithout opening a single channel by hand. - 📈 YouTube SEO and content strategists: pull
video/shorttitles andpublishedTimeTextfrom competing channels found by keyword to spot content gaps and upload cadence in a niche. - 🤖 AI engineers and LLM developers: issue a keyword query, get back structured JSON, and pass
channelandvideorows directly to a model as grounded context for a research or outreach agent. - 📊 Market and competitor researchers: track
numberOfSubscribers,channelTotalViews, anddiscoveryRankacross a keyword set over time to measure share-of-voice shifts in a category.
📉 How do you monitor YouTube channels and their growth over time?
Monitoring here means running the same keyword set (or the same startUrls) on a schedule and diffing the results — a single snapshot only tells you where a channel stood the moment it was scraped. Because every row carries scrapedAt, and channel rows carry numberOfSubscribers, channelTotalViews, and channelTotalVideos, two runs of the same channel a week apart give you a growth delta without any extra tooling.
The fields worth diffing between runs: numberOfSubscribers and channelTotalViews for growth, channelTotalVideos for upload volume, and — specific to keyword discovery — discoveryRank and discoveryFoundByQueries, since YouTube's own channel search is not a stable ranking and a channel's position (or presence at all) in a keyword's results can shift between runs. video/short rows let you diff viewCount and likesCount on the same videoId to see how individual uploads are performing over time.
A typical workflow: schedule a run across your keyword set (via Apify's built-in Scheduler), compare each new dataset against the previous run's export keyed on channelId (and videoId for item-level rows), and alert when a subscriber count crosses a threshold or a channel drops out of a keyword's top results entirely.
🔌 Integrate this Actor and automate your workflow
This Actor works with any language or tool that can send an HTTP request, through the Apify API and the apify-client SDKs.
REST API with Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run = client.actor("<username>/youtube-channel-scraper-channel-search").call(run_input={"searchQueries": ["home workout"],"maxChannelsPerQuery": 10,"minSubscribers": 100000,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["rowType"], item.get("channelName") or item.get("title"))
Scheduled monitoring and delivery
There is no built-in webhook push for individual events, but the Apify platform's Schedules let you run this Actor on a recurring cadence, and webhooks can fire on run completion (e.g. to notify a pipeline that a new dataset is ready). For continuous monitoring, schedule the run and pull the dataset with apify-client after each run finishes, or use a webhook to trigger that pull automatically.
⚖️ Is it legal to scrape YouTube channel data?
Yes — scraping publicly visible YouTube pages is generally lawful when you're only reading data any visitor can see without logging in, and this Actor returns only that: public channel, video, and community-post information. In hiQ Labs v. LinkedIn Corp (9th Cir. 2019), the court held that scraping publicly accessible data does not violate the Computer Fraud and Abuse Act, a precedent frequently cited for public-web scraping generally.
That said, channel names, handles, subscriber counts, and community-post text can identify a real person, so this data can qualify as personal data under GDPR (EU/UK) and the CCPA (California) even though it's public — those regimes govern how personal data is collected, stored, and reused, not just whether it was public when collected. YouTube's own Terms of Service also restrict automated access, which is a separate, contractual risk from the public-data legal question. Scraping for operational monitoring (outreach lists, competitor tracking) and scraping to build an AI training set carry different risk profiles under both regimes. Consult your legal team for commercial use cases involving bulk data storage.
❓ Frequently asked questions
Does the search market (searchMarket) change which channels I find?
Yes. searchMarket (e.g. en-US, de-DE, pt-BR) controls the language and country YouTube's channel search runs in, and different markets return different channels for the same keyword. Channel pages themselves are always fetched in English (hl=en&gl=US) regardless of searchMarket, so tab names and sort chips stay readable.
What does sortOrderVideos actually control?
It picks which of the Videos tab's own sort chips to request: date (newest first, the default), viewCount (most viewed first), or oldest (first uploads first). If a channel doesn't offer the Popular or Oldest chip, the Actor falls back to newest-first and the run log says so. Shorts, Live, and Community tabs have no sort chips on YouTube at all, so those three are always returned in YouTube's own order — there's no equivalent setting for them.
How does this Actor handle YouTube's anti-bot and consent walls?
Every request goes through Apify Proxy (residential by default, since datacenter IPs are more likely to trigger a consent or bot interstitial), and consent cookies are set automatically. If a channel page or an exact-count lookup comes back bot-walled and no rows have been pushed yet for that channel, the Actor retries once on a fresh proxy session before giving up and logging the channel as failed.
Does this Actor extract community posts?
Yes — scrapePosts (on by default) emits one post row per Community-tab post, including postType, textContent, imageUrls, pollOptions, and attachedVideoId for video/playlist shares. This is data the official YouTube Data API v3 does not expose at all, since it has no resource for the Community tab.
How many channels can one keyword return?
maxChannelsPerQuery caps channels kept per keyword (default 5, max 500), and maxChannels caps the total across all keywords in the run (default 10, max 1000). Internally, discovery pages through up to 25 of YouTube's own search-result pages per keyword (about 20 channels per page), which is the practical ceiling behind the 500 maximum.
How many videos, Shorts, streams, and posts does it return per channel?
maxResults (default 10, max 1000) applies independently to each enabled section — videos, Shorts, live streams, and posts — per channel. A channel with no Shorts, Live, or Community tab returns zero rows for that section rather than substituting anything.
How do I monitor a channel's subscriber count or ranking over time?
Schedule the same keyword set or channel list to run repeatedly (via Apify's Scheduler), and diff numberOfSubscribers, channelTotalViews, and — for keyword-discovered channels — discoveryRank between runs, keyed on channelId. YouTube's channel search ranking is not fixed, so discoveryRank reflects that run only, not a permanent position.
Does this Actor work with Claude, ChatGPT, or AI agent frameworks?
It's callable as an HTTP endpoint through the Apify API using any language or agent framework's HTTP client, or via the apify-client Python/JS SDKs — an agent can issue a keyword query, receive the structured JSON dataset, and use it as grounded context before generating an answer.
Can I use this Actor without managing proxies or a YouTube login?
Yes. Apify Proxy is configured by default (US residential) and attached to every request the Actor makes, and no YouTube account or login is required since everything scraped is public data. You only need an Apify account to run the Actor.
What happens if I don't provide any keywords or channel links?
The run fails immediately with an error telling you to provide at least one keyword in searchQueries or at least one channel in startUrls — the input schema marks both optional, but the Actor needs at least one of them to have anything to scrape.
💬 Your feedback
Found a bug, or a field that's missing or wrong? Open an issue on this Actor's Apify Store page, or reach out through Apify Console — reports help keep the scraper aligned with YouTube's current page structure.