A smart desktop video scraper built with Python, PyQt6, Playwright, and yt-dlp.
VideoBot crawls listing/gallery pages, follows each item to its detail page, downloads the video, waits 5 seconds (always), then moves on — page after page until you tell it to stop.
- Dual-engine download
- yt-dlp handles YouTube, Vimeo, Twitter/X, TikTok, Dailymotion, Reddit, and 1000+ other platforms automatically
- Playwright direct extraction falls back for sites with raw
<video>tags, MP4/WebM links, og:video meta, JSON-LD VideoObject, anddata-*attributes
- Smart two-phase crawler — JS scoring heuristic finds item page links on listing/gallery pages, same approach as ScrapeBot
- Quality selector — Best, 1080p, 720p, 480p, or Worst
- Format preference — MP4, WebM, or Any
- Respectful rate limiting — hardcoded 5-second wait after every download, never skipped
- File validation — rejects files under 100 KB
- Unlimited pagination — auto-clicks next page until max pages reached or Stop pressed
- Dark desktop UI — live stat cards, scrolling log, progress bar
- Python 3.9+
- ffmpeg (for merging video+audio tracks from YouTube etc.)
brew install ffmpeg
git clone https://github.com/Shadowfetchapps/videobot.git
cd videobot
pip install -r requirements.txt
playwright install chromiumpython run.pyVideoBot.app runs run.py from the folder it sits in, so it works from any clone location. It uses .venv/bin/python3 in the repo folder if that exists, otherwise python3 from your login shell, and it runs run.py with your login-shell PATH, so Homebrew tools such as ffmpeg are on the PATH. Set up the venv once:
cd videobot
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/playwright install chromiumThen double-click VideoBot.app in the repo folder. Keep the app inside the repo folder; it looks for run.py next to itself. Output goes to ~/Library/Logs/VideoBot.log. If Python or the requirements are missing, the app shows a dialog with the setup commands.
The app is ad-hoc signed, not notarized. A git clone launches directly. If you downloaded the repo as a ZIP, macOS blocks the first launch: right-click the app and choose Open (on macOS 15 and later, try to open it once, then click Open Anyway in System Settings > Privacy & Security), or run xattr -dr com.apple.quarantine VideoBot.app in the repo folder.
- Paste a listing or gallery URL into Start URL
- Works with YouTube channels/playlists, Vimeo showcases, video grid sites, etc.
- Choose a Save To folder (defaults to
~/Downloads/VideoBot) - Select Quality and Format
- Set Max Pages —
∞ Unlimitedruns until you click Stop - Click ▶ Start Scraping
| Card | What it counts |
|---|---|
| Listing Pages | Gallery/listing pages crawled |
| Items Visited | Individual item URLs followed |
| Videos Saved | Files actually downloaded |
Shows real-time progress: page URLs, item URLs, yt-dlp messages, download results, 5-second delay countdowns, and final totals.
Playwright loads the gallery page and runs a JS scoring heuristic over every <a> tag:
| Signal | Points |
|---|---|
Wraps <img> or <video> |
+6 |
| Inside a card/grid/feed container | +4 |
URL path contains /video/, /watch/, /clip/, etc. |
+3 |
URL contains ?v= |
+3 |
Has aria-label or title attribute |
+1 each |
Links scoring ≥ 4 are collected. The next-page URL is found via rel="next", class-name heuristics, and text content (Next, ›, »).
For every item URL, VideoBot tries two strategies in order:
A. yt-dlp — attempts to extract and download using the selected quality/format. Handles platform authentication cookies, HLS streams, DASH, and format merging via ffmpeg.
B. Playwright direct extraction — opens the page and scans for video sources using 6 strategies:
<video src>and<video><source src>og:video/og:video:secure_urlmeta tags- JSON-LD
VideoObjectwithcontentUrl <a href>links ending in.mp4,.webm,.mkv, etc.data-video-url,data-src,data-stream, etc.- YouTube/Vimeo
<iframe>embed URLs
After every successful download a 5-second delay is enforced before moving to the next item.
| Format | Extensions |
|---|---|
| MP4 | .mp4, .m4v |
| WebM | .webm |
| Matroska | .mkv |
| QuickTime | .mov |
| AVI | .avi |
| Flash Video | .flv |
| Windows Media | .wmv |
| MPEG | .mpeg, .mpg |
| Mobile | .3gp, .ogv |
- yt-dlp must be installed and ffmpeg must be on your PATH for best results
- Some sites require being logged in — yt-dlp supports
--cookies-from-browserfor this (add toydl_optsinscraper.py) - Private or age-gated content will require browser cookies; this is not configured by default
- VideoBot respects the 5-second rule even across page turns — it never batches or skips the delay
videobot/
├── videobot/
│ ├── __init__.py
│ ├── app.py # PyQt6 dark UI
│ ├── worker.py # QThread background worker
│ └── scraper.py # SmartVideoScraper (yt-dlp + Playwright)
├── VideoBot.app # Double-clickable macOS launcher
├── requirements.txt
├── run.py
└── README.md
MIT. See LICENSE.