A YouTube search page tells you less than it seems to. The view counts on the result cards are rounded ("298K views"), the dates are vague ("2 years ago"), and likes, tags and the channel's subscriber count are not there at all. To size up a niche, find creators who outperform their channel size or keep a feed of what competitors upload, you need the numbers from each video's own watch page, in a table.
This post pulls YouTube search results, channels and playlists into Python with full video details, finds the videos that punch above their channel's size, and sets up a daily feed of new uploads.
Disclosure: I'm Aurelix, and I built the YouTube Video Scraper. It's a paid tool (prices below).
What each row holds
One row per video, read from its public watch page during your run:
-
video_id,url,title,description,description_links,duration_seconds. -
published_at(exact time, ISO 8601 UTC) andpublished_date. -
view_countandlike_count, exact at the time of the run;like_countis null when the creator hides likes. -
comment_countandcomment_count_textas YouTube shows them (exact below 1,000, rounded above). - The channel:
channel_name,channel_id,channel_handle,channel_url,channel_verified,channel_subscribersandchannel_subscribers_text. -
tags,hashtags,category,chapters({title, start, end}),has_captions,caption_languages. -
is_short,is_live,is_upcoming,is_unlisted, thumbnails, and where the row came from:source,source_type,source_position.
A keyword search as a sheet
pip install apify-client
import csv
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("aurelix/youtube-video-scraper").call(
run_input={
"searchTerms": ["home espresso", "espresso grinder"],
"sort": "popularity",
"uploadDate": "month",
"duration": "3to20",
"maxResults": 50,
}
)
videos = list(client.dataset(run["defaultDatasetId"]).iterate_items())
fields = ["source", "source_position", "title", "channel_name", "published_at", "view_count",
"like_count", "comment_count", "channel_subscribers", "url"]
with open("youtube_search.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
w.writeheader()
w.writerows(videos)
sort, uploadDate, videoType, duration, features (such as hd or subtitles) and country are YouTube's own search filters, so the rows match what a viewer in that country sees. source_position is the video's place in the results for that search term. A search on YouTube shows at most a few hundred results, so split broad topics into several terms.
Which videos punch above their channel's size
Views alone favour big channels. Dividing by the channel's subscribers shows which small creators are getting outsized reach on a topic, which is where partnership and content ideas usually are:
rows = [v for v in videos if v.get("view_count") and v.get("channel_subscribers")]
for v in sorted(rows, key=lambda v: v["view_count"] / v["channel_subscribers"], reverse=True)[:10]:
ratio = v["view_count"] / v["channel_subscribers"]
likes = v["like_count"] if v["like_count"] is not None else "hidden"
print(f'{ratio:6.1f}x {v["channel_name"][:28]:28} {v["view_count"]:>10,} views {likes} likes {v["title"][:50]}')
The same rows group well by channel_id for creator research: subscriber count, verified badge and the views of each channel's recent videos in one place. tags and category show how the top videos are labelled.
A date range on any input
run = client.actor("aurelix/youtube-video-scraper").call(
run_input={
"searchTerms": ["electric cars"],
"publishedAfter": "90 days",
"publishedBefore": "30 days",
"maxResults": 200,
}
)
publishedAfter and publishedBefore take a date (2026-01-31) or an age (7 days, 12 hours, 3 months) and are checked against each video's exact publish time. Videos outside the range are skipped and not charged.
Competitors' new uploads, every morning
Channels take URLs, @handles or UC… IDs. Pick the tab with channelTab (videos, shorts or streams) and the order with channelSort (latest, popular, oldest):
run = client.actor("aurelix/youtube-video-scraper").call(
run_input={
"channels": ["@mkbhd", "@veritasium"],
"maxResults": 10,
"incremental": True,
"stateKey": "competitor-feed",
"slackWebhookUrl": "https://hooks.slack.com/services/T000/B000/XXXX",
}
)
new = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(len(new), "new videos")
With incremental on, the first run returns every matching video. Each later run with the same stateKey returns only videos earlier runs did not, and on a channel in latest order it stops at the first one already returned, so a daily run reads little. Save the input as a task in the Apify Console and schedule it daily; the Slack URL gets the count and the top 10 new videos with links, and nothing is sent when a run finds nothing. webhookUrl posts the same digest as JSON to Zapier, Make or n8n.
Why this tool
- Every row comes from the video's own watch page: exact views and likes, exact publish time, tags, category and channel size.
- Search terms, video links, channels and playlists in one run, deduplicated.
- YouTube's own search filters plus a from-to date range at no extra fee.
- An only-new mode with a Slack or webhook digest for daily feeds.
- What it doesn't cover: transcripts. For those, YouTube Transcript Scraper takes the same inputs.
Limits
-
Rounded counts where YouTube rounds them. Comment and subscriber counts are exact below 1,000 and rounded above; the text forms are in the
_textfields. - About 1 to 2 seconds per video in a long run, because each video is a full page.
-
details_completefalse on a row means YouTube withheld the player data from every IP tried; that row still has views, likes, comments and the channel, with publish time, tags and category null. - No comments or viewer data. It reads public video and channel details only, and never logs in.
Cost
$0.25 per 1,000 videos ($0.23 on paid Apify plans), plus a $0.01 start fee per run. Filters, the date range and only-new mode cost nothing extra, and duplicates, unavailable videos and videos outside your date range are never charged. The current prices are on the Store page; Apify's free plan includes $5 of credit a month, about 19,000 videos.
Top comments (0)