reddit-universal-scraper

ksanjeev284MIT活跃维护

一个通用的 Reddit 爬虫,能抓取任意子版块或用户的内容,适合做数据采集和舆情分析。

Universal Reddit Scraper - Works on any Subreddit or User

暂无版本614star +2 / 7 天94fork同步于 2026-11-10 23:55 UTC

怎么上手

由 README 提炼,执行前请确认
pip install -r requirements.txt
python main.py --check-access
python main.py python --mode full --limit 100
硬件要求按 README 说明

README 未说明 GPU 或显存要求;仅需 Python 3.10+,ffmpeg 为可选(处理带音频视频时用),可纯 CPU 运行,也可用 Docker 部署。

有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

抓取任意 subreddit 或用户帖子的 Reddit 爬虫,自带仪表盘、REST API 和定时任务

一个通用的 Reddit 爬虫,能抓取任意子版块或用户的内容,适合做数据采集和舆情分析。

核心能力

  • 支持 full/history/monitor 三种抓取模式,可抓帖子、评论和媒体
  • 内置 Streamlit 七标签仪表盘,可视化统计与搜索
  • 提供 REST API,可接 Metabase、Grafana、DuckDB
  • 插件系统支持情感分析、去重、关键词提取
  • 支持 cron 式定时抓取与 Discord/Telegram 通知

容易踩的坑

Reddit 会拦截未认证 API 流量,需先在 .env 配置获批的 OAuth 凭据,否则直接失败;抓取只覆盖列表页有限窗口和已加载的评论树,more 占位符不会展开,也拿不到完整历史归档;仪表盘默认 8501 端口、API 默认 8000 端口,部署到服务器需自行放行。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

0 个版本

暂无 release 数据(可能没有发版,或尚未同步)。

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    🤖 Universal Reddit Scraper Suite

    Docker Build & Publish

    A full-featured Reddit scraper with analytics dashboard, REST API, scheduled scraping, plugins, and more. Two collection modes: free browser-page capture, or approved OAuth API access.

    ✨ Features

    FeatureDescription
    📊 Full ScrapingAvailable posts, loaded comments, images, videos, galleries
    📈 Web DashboardBeautiful Streamlit UI with 7 tabs
    🚀 REST APIConnect Metabase, Grafana, DuckDB
    🔌 Plugin SystemExtensible post-processing (sentiment, dedupe, keywords)
    📋 Job TrackingFull history with status, duration, errors
    🧪 Dry Run ModeTest scrape rules without saving data
    📦 Parquet ExportAnalytics-ready format for DuckDB/warehouses
    😀 Sentiment AnalysisAnalyze post/comment sentiment
    📅 Scheduled ScrapingCron-style job scheduling
    📧 NotificationsDiscord & Telegram alerts
    🗄️ SQLite DatabaseStructured storage with auto-backup

    🚀 Quick Start

    # Install dependencies
    pip install -r requirements.txt
    
    # Configure approved API credentials (see .env.example)
    # Copy .env.example to .env only if you do not already have .env
    python main.py --check-access
    
    # Scrape a subreddit
    python main.py python --mode full --limit 100
    
    # Launch dashboard
    python main.py --dashboard
    # Opens at http://localhost:8501
    

    📋 Requirements

    • Python 3.10+
    • ffmpeg (optional, for video with audio)
    # Windows (via chocolatey)
    choco install ffmpeg
    
    # macOS
    brew install ffmpeg
    
    # Ubuntu/Debian
    sudo apt install ffmpeg
    

    Free browser extension

    The Browser Collector Companion works independently in Chrome/Edge while you browse Reddit signed in. It captures loaded posts, comments and media links, supports filters and session limits, and exports JSON or CSV without paid services or API keys. It can also send collections to the application for database storage, dashboard analytics and search. Collect only data you are authorized to use.

    Load the extension/ folder through Developer mode → Load unpacked, reload Reddit, then use Start capture or Capture this page. It observes loaded content as you browse; it does not retrieve an entire archive or automatically expand unloaded comments.

    # Connect the extension to the application
    python main.py --api
    # In another terminal: copy this pairing token into the extension
    python main.py --bridge-token
    
    # Or import a standalone JSON export without starting the API
    python main.py --import-browser path/to/export.json
    
    # Build the unpackable release ZIP
    python scripts/package_extension.py
    

    Pairing uses optional localhost permissions and a local token. The browser's Reddit cookies remain in the browser. Python proxy support remains available, including stable country/session targeting; the extension uses your existing browser proxy settings.

    Reddit access and reliability

    Reddit blocks unauthenticated API traffic. The direct Python scraper uses oauth.reddit.com with a descriptive User-Agent, cached OAuth tokens, token renewal, bounded retries and shared request pacing. Both sync and async scrapers respect Retry-After and Reddit rate-limit headers. API requests are serialized within each client; media downloads remain concurrent. Independent processes share your app quota, so schedule them accordingly.

    See Reddit access setup for credentials, restrictions, troubleshooting and the Developer Platform migration timeline. Missing credentials, denied access, HTML responses and exhausted retries produce explicit failures. CLI failures exit with status 1; jobs preserve collected posts and report failed status when a later request fails.

    An optional stable network proxy can be configured with PROXY_URL or --proxy. ScrapingAnt country/session targeting is available through PROXY_COUNTRY / --proxy-country and PROXY_SESSION_ID / --proxy-session. --proxy none disables it. Mirrors, browser impersonation, warm-up requests and automatic proxy rotation are no longer used. A proxy does not grant API approval.

    Listings expose a limited window of posts, not a complete historical archive. Comment collection includes the initially loaded tree up to the configured depth; more placeholders are not expanded. Deleted or restricted content cannot be recovered.


    📖 All Commands

    🔄 Scraping

    # Collect available posts + media + loaded comments
    python main.py delhi --mode full --limit 100
    
    # Fast history-only (no media/comments)
    python main.py delhi --mode history --limit 500
    
    # Live monitor (checks every 5 min)
    python main.py delhi --mode monitor
    
    # Scrape a user's posts
    python main.py spez --user --mode full --limit 50
    
    # Skip media or comments
    python main.py delhi --no-media --limit 200
    python main.py delhi --no-comments --limit 200
    

    🧪 Dry Run Mode

    Test scrape rules without saving any data:

    python main.py python --mode full --limit 50 --dry-run
    

    Output:

    🧪 DRY RUN MODE - No data will be saved
    🧪 DRY RUN COMPLETE!
       📊 Would scrape: 100 posts
       💬 Would scrape: 245 comments
    

    🔌 Plugins

    Enable post-processing plugins:

    # List available plugins
    python main.py --list-plugins
    
    # Run with plugins enabled
    python main.py python --mode full --plugins
    

    Built-in Plugins:

    PluginDescription
    sentiment_taggerAdds sentiment scores to posts
    deduplicatorRemoves duplicate posts
    keyword_extractorExtracts top keywords

    Create custom plugins in plugins/ folder.

    📊 Dashboard

    python main.py --dashboard
    # Opens at http://localhost:8501
    

    Dashboard Tabs:

    • 📊 Overview - Stats & charts
    • 📈 Analytics - Sentiment & keywords
    • 🔍 Search - Query scraped data
    • 💬 Comments - Comment analysis
    • ⚙️ Scraper - Start new scrapes
    • 📋 Job History - View all jobs
    • 🔌 Integrations - API, export, plugins

    🚀 REST API

    python main.py --api
    # API at http://localhost:8000
    # Docs at http://localhost:8000/docs
    

    Endpoints:

    EndpointDescription
    GET /postsList posts with filters
    GET /commentsList comments
    GET /subredditsAll scraped subreddits
    GET /jobsJob history
    GET /query?sql=...Raw SQL queries
    GET /grafana/queryGrafana time-series

    📦 Export & Maintenance

    # Export to Parquet (for DuckDB/warehouses)
    python main.py --export-parquet python
    
    # View job history
    python main.py --job-history
    
    # Backup database
    python main.py --backup
    
    # Optimize database
    python main.py --vacuum
    

    📅 Scheduled Scraping

    # Scrape every 60 minutes
    python main.py --schedule delhi --every 60
    
    # With options
    python main.py --schedule delhi --every 30 --mode full --limit 50
    

    🔍 Search & Analytics

    # Search scraped data
    python main.py --search "credit card" --min-score 100
    
    # Run sentiment analysis
    python main.py --analyze delhi --sentiment
    
    # Extract keywords
    python main.py --analyze delhi --keywords
    

    🐳 Docker

    Quick Start

    # Build
    docker build -t reddit-scraper .
    
    # Run scrape
    docker run --env-file .env -v ./data:/app/data reddit-scraper python --limit 100
    
    # Run with plugins
    docker run --env-file .env -v ./data:/app/data reddit-scraper python --plugins
    

    Docker Compose (Full Stack)

    # Start API + Dashboard
    docker-compose up -d
    
    # Access:
    # Dashboard: http://localhost:8501
    # API: http://localhost:8000/docs
    

    Deploy to AWS/VPS

    # SSH into your server
    ssh user@your-server-ip
    
    # Clone repo
    git clone https://github.com/ksanjeev284/reddit-universal-scraper.git
    cd reddit-universal-scraper
    
    # Start services
    docker-compose up -d
    
    # Open firewall ports
    sudo ufw allow 8000
    sudo ufw allow 8501
    

    Access:

    • http://your-server-ip:8501 → Dashboard
    • http://your-server-ip:8000/docs → API

    🔗 External Integrations

    Metabase

    1. Start API: python main.py --api
    2. Add HTTP datasource: http://localhost:8000
    3. Query: /posts?subreddit=python&limit=100

    Grafana

    1. Install "JSON API" or "Infinity" plugin
    2. Add datasource: http://localhost:8000
    3. Use /grafana/query for time-series

    DuckDB

    import duckdb
    
    # Export to Parquet first
    # python main.py --export-parquet python
    
    # Query directly
    duckdb.query("SELECT * FROM 'data/parquet/*.parquet'").df()
    

    📁 Project Structure

    reddit-scraper/
    ├── main.py              # CLI entry point
    ├── config.py            # Settings
    ├── analytics/           # Sentiment & keywords
    ├── alerts/              # Discord/Telegram
    ├── api/                 # REST API server
    ├── dashboard/           # Streamlit UI
    ├── export/              # Database & exports
    ├── plugins/             # Post-processing plugins
    ├── scheduler/           # Cron scheduling
    ├── search/              # Search engine
    └── data/
        ├── r_subreddit/     # Scraped data
        ├── backups/         # DB backups
        └── parquet/         # Parquet exports
    

    📊 Data Output

    posts.csv

    ColumnDescription
    idReddit post ID
    titlePost title
    authorUsername
    scoreNet upvotes
    num_commentsComment count
    post_typetext/image/video/gallery
    selftextPost body
    sentiment_score-1.0 to 1.0 (with plugins)

    comments.csv

    ColumnDescription
    comment_idComment ID
    post_permalinkParent post
    authorUsername
    bodyComment text
    scoreUpvotes

    ⚙️ Environment Variables

    # Notifications
    export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
    export TELEGRAM_BOT_TOKEN="123456:ABC..."
    export TELEGRAM_CHAT_ID="987654321"
    

    📜 License

    MIT License - Feel free to use, modify, and distribute.

    🤝 Contributing

    Pull requests welcome! For major changes, please open an issue first.