Personal YouTube subscriptions scraper that ranks videos and generates a static feed.
Project description
YouTube subscriptions viewer
A local web app that displays your YouTube subscription videos sorted by a sophisticated performance algorithm. The scoring system uses multiple factors to surface high-quality content while giving smaller channels a fair chance to compete.
Ranking Algorithm
The performance score is calculated using a weighted combination of factors, designed to surface exceptional videos even when the scraper is run sporadically:
-
Base Performance (35% weight)
- Compares video views to the channel's average (capped at 5×)
- Highlights true standouts within each channel's history
-
Engagement Rate (25% weight)
- Rewards videos reaching 10%+ of subscribers
- Square-root scaling to give diminishing returns without punishing lower reach
-
Forecasted 48h Performance (20% weight)
- Projects total views at 48h assuming ~60% arrive in the first 8h and ~95% by 48h
- Gives very new uploads credit for strong early velocity
-
Velocity Metric (10% weight)
- Views per hour since publication, logarithmically scaled as a bonus
- Keeps currently surging content competitive without penalizing slower burns
-
Channel Size Normalization (7% weight)
- Small channels (<100k subs): +7% bonus
- Medium channels (100k-1M): +5% bonus
- Large channels (1M-10M): +2% bonus
- Helps smaller creators compete fairly
-
Duration Adjustment (3% weight)
- Slightly boosts videos in the 10–30 minute sweet spot
- Keeps short/long content competitive without heavy bias
This scoring system keeps the focus on videos that outperform their channel norms, credits early momentum as a forecast (not just recency), and avoids decaying scores just because content is older when you run the scraper.
Overview
A tool to track YouTube subscriptions and surface high-performing videos. It consists of:
- A channel stats scraper that collects subscriber counts and average views
- A video scraper that collects new videos from subscribed channels
- A static page generator that creates a feed of videos sorted by performance
Quick start (recommended: uvx)
You can run the tool directly with uvx — no cloning and no manual installs:
uvx ytsubs scrape-channels
uvx ytsubs scrape-videos
uvx ytsubs open
Setup (local dev)
-
Requirements:
- Python 3.12+
- Google Chrome browser
-
(Optional) Install tool versions with mise:
mise install
- Install dependencies with uv:
uv sync
Usage
First-time setup
Run these commands in order:
uv run ytsubs scrape-channels # When Chrome opens, log in to YouTube
uv run ytsubs scrape-videos # Collect recent videos and generate the feed
uv run ytsubs open # Open the feed in your browser
Your YouTube login is saved in ~/.local/state/ytsubs/chrome_profile (or $XDG_STATE_HOME/ytsubs/chrome_profile), so you'll only need to log in once. Subsequent runs will reuse this profile.
Regular usage
- Collect video data:
uv run ytsubs scrape-videos # Run daily to get new videos
- Update channel statistics (subscriber counts, average views):
uv run ytsubs scrape-channels # Run occasionally (e.g., monthly)
- Open the feed:
uv run ytsubs open # Opens the latest feed
The feed is written to ~/.local/state/ytsubs/ytsubs_feed.html (or $XDG_STATE_HOME/ytsubs/ytsubs_feed.html).
Data locations (XDG)
- Chrome profile:
~/.local/state/ytsubs/chrome_profile(or$XDG_STATE_HOME/ytsubs/chrome_profile) - SQLite DB:
~/.local/state/ytsubs/youtube.db(or$XDG_STATE_HOME/ytsubs/youtube.db) - Feed output:
~/.local/state/ytsubs/ytsubs_feed.html(or$XDG_STATE_HOME/ytsubs/ytsubs_feed.html)
Debug tooling
uv run ytsubs debug-scrape --scrolls 4 --filter "gymkhana"
Development
The project uses:
- SQLite for data storage
- Playwright for web scraping
- Preact for the frontend (served statically)
Makefile commands
The project includes several helpful make commands:
make clean: Remove Python cache filesmake reset-db: Reset database to empty tablesmake reset-videos: Clear only the videos tablemake reset-channels: Clear only the channels table
Requirements
- Python 3.12+
- Google Chrome
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ytsubs-0.1.1.tar.gz.
File metadata
- Download URL: ytsubs-0.1.1.tar.gz
- Upload date:
- Size: 31.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bd47b3c4983b7622225b91d69d73b1112ce1894410d9f29a3db4ed62919c9e9
|
|
| MD5 |
b98d90defd6f8cdfb53672b602c177b7
|
|
| BLAKE2b-256 |
101515f486a77cee485cf0998c1b410f3091870e162d4b1e33ee2b713b4bcda9
|
Provenance
The following attestation bundles were made for ytsubs-0.1.1.tar.gz:
Publisher:
publish.yml on shayne/ytsubs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ytsubs-0.1.1.tar.gz -
Subject digest:
8bd47b3c4983b7622225b91d69d73b1112ce1894410d9f29a3db4ed62919c9e9 - Sigstore transparency entry: 774309397
- Sigstore integration time:
-
Permalink:
shayne/ytsubs@19cf7af7da8fee2289c7dbd43ca649f5f5c01817 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/shayne
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@19cf7af7da8fee2289c7dbd43ca649f5f5c01817 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ytsubs-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ytsubs-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e37e1e49c4df116ef3a4ff173bbdff41d97a5b6497ea263c060d1260861db2a
|
|
| MD5 |
acc27e2198e896f888132dde6576d2da
|
|
| BLAKE2b-256 |
e62a668201ffbabe3e9f5687064eb968c7c4715a5a2cd095ab723690b8a783e8
|
Provenance
The following attestation bundles were made for ytsubs-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on shayne/ytsubs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ytsubs-0.1.1-py3-none-any.whl -
Subject digest:
0e37e1e49c4df116ef3a4ff173bbdff41d97a5b6497ea263c060d1260861db2a - Sigstore transparency entry: 774309400
- Sigstore integration time:
-
Permalink:
shayne/ytsubs@19cf7af7da8fee2289c7dbd43ca649f5f5c01817 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/shayne
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@19cf7af7da8fee2289c7dbd43ca649f5f5c01817 -
Trigger Event:
workflow_dispatch
-
Statement type: