궁극적인 Reddit 스크래퍼 구축: 풀-피처드, API-프리 데이터 수집 스위트

발행: (2025년 12월 14일 오전 09:30 GMT+9)
9 min read
원문: Dev.to

Source: Dev.to

TL;DR

API 키가 전혀 필요 없는 완전한 Reddit 스크래퍼 스위트를 만들었습니다. Streamlit 대시보드, Grafana·Metabase와 같은 도구와 연동할 수 있는 REST API, 포스트‑프로세싱을 위한 플러그인 시스템, 예약 스크래핑, 알림 등 다양한 기능을 포함하고 있습니다. 가장 좋은 점은—전부 오픈 소스라는 점입니다.

🔗 GitHub:

The Problem

Reddit 데이터를 분석, 연구, 혹은 개인 프로젝트에 활용하려고 시도해 본 적이 있다면 다음과 같은 문제에 직면했을 가능성이 높습니다.

  • Reddit API는 매우 제한적인 레이트‑리밋을 가지고 있음(특히 2023년 API 변경 이후)
  • API 키는 승인 절차가 필요하고 점점 더 제한되고 있음
  • 기존 스크래퍼들은 보통 단일 목적—게시물 또는 댓글만 스크래핑함
  • 스크래핑 후 데이터를 시각화하거나 분석할 쉬운 방법이 없음
  • 수동으로 스크래핑을 실행하는 것은 번거롭고 자동화가 필요함

The Solution: Universal Reddit Scraper Suite

수 주에 걸친 개발 끝에 다음과 같은 완전한 기능을 갖춘 스크래퍼를 만들었습니다.

FeatureWhat It Does
📊 Full Scraping게시물, 댓글, 이미지, 비디오, 갤러리—모두 포함
🚫 No API KeysReddit의 공개 JSON 엔드포인트와 미러를 사용
📈 Web Dashboard분석을 위한 아름다운 7‑탭 Streamlit UI
🚀 REST APIMetabase, Grafana, DuckDB 등과 연결
🔌 Plugin System확장 가능한 포스트‑프로세싱(감성 분석, 중복 제거, 키워드 추출)
📅 Scheduled ScrapingCron‑스타일 자동화
📧 Notifications스크래핑 완료 시 Discord·Telegram 알림
🐳 Docker Ready한 줄 명령으로 어디서든 배포 가능

Architecture Deep Dive

How It Works Without API Keys

공식(그리고 제한된) Reddit API 대신, 스크래퍼는 다음을 활용합니다.

  • Public JSON endpoints – 모든 Reddit 페이지는 .json 접미사를 붙이면 구조화된 데이터를 반환합니다.
  • Multiple mirror fallbacks – 하나의 소스가 레이트‑리밋에 걸리면 스크래퍼가 자동으로 다른 미러로 전환합니다.
MIRRORS = [
    "https://old.reddit.com/",
    "https://redlib.catsarch.com/",
    "https://redlib.vsls.cz/",
    "https://r.nf/",
    "https://libreddit.northboot.xyz/",
    "https://redlib.tux.pizza/",
]

소스가 실패하면 다음 미러가 자동으로 시도됩니다—수동 개입이 필요 없습니다.

The Core Scraping Engine

스크래퍼는 세 가지 모드로 동작합니다.

Full Mode – Complete package

python main.py --mode full --limit 100

게시물을 스크랩하고 모든 미디어(이미지, 비디오, 갤러리)를 다운로드하며, 전체 스레드 구조를 가진 댓글을 가져옵니다.

History Mode – Fast metadata‑only

python main.py --mode history --limit 500

미디어를 다운로드하지 않고 게시물 메타데이터만 수집해 데이터셋을 구축합니다.

Monitor Mode – Live watching

python main.py --mode monitor

5분마다 새로운 게시물을 지속적으로 확인합니다. 최신 뉴스나 트렌드 토론을 추적하기에 적합합니다.

The Dashboard Experience

7‑탭 Streamlit 대시보드는 데이터 탐색을 직관적으로 만들어 줍니다.

Overview Tab

  • 총 게시물 및 댓글 수
  • 전체 게시물의 누적 점수
  • 미디어 게시물 비율
  • 시간별 게시물 차트
  • 점수 기준 상위 10개 게시물

Analytics Tab

  • Sentiment Analysis – 전체 데이터셋에 대한 VADER 기반 감성 점수
  • Keyword Cloud – 가장 많이 사용된 용어
  • Best Posting Times – 최적의 참여 시간을 데이터 기반으로 제시

Search Tab

필터와 함께 전체 텍스트 검색 제공:

  • 최소 점수
  • 게시물 유형(텍스트, 이미지, 비디오, 갤러리, 링크)
  • 작성자
  • 사용자 정의 정렬

Comments Analysis

  • 최고 점수 댓글 보기
  • 가장 활발한 댓글 작성자 파악
  • 시간에 따른 댓글 패턴 추적

Scraper Controls

대시보드에서 직접 새로운 스크래핑을 시작할 수 있습니다. 설정 가능한 옵션:

  • 대상 subreddit/사용자
  • 게시물 제한 수
  • 모드(full/history)
  • 미디어 및 댓글 토글

Job History

각 스크래핑 작업에 대한 가시성 제공:

  • 상태(실행 중, 완료, 실패)
  • 소요 시간 메트릭
  • 게시물/댓글/미디어 수
  • 오류 로그

Integrations

다음 서비스와 연결하기 위한 사전 구성된 안내:

  • Metabase
  • Grafana
  • DreamFactory
  • DuckDB

The Plugin Architecture

간단하면서도 강력한 확장 가능한 포스트‑프로세싱 시스템입니다.

class Plugin:
    """Base class for all plugins."""
    name = "base"
    description = "Base plugin"
    enabled = True

    def process_posts(self, posts):
        return posts

    def process_comments(self, comments):
        return comments

Built‑in Plugins

Sentiment Tagger

게시물·댓글에 VADER 감성 점수와 라벨을 추가합니다.

class SentimentTagger(Plugin):
    name = "sentiment_tagger"
    description = "Adds sentiment scores and labels to posts"

    def process_posts(self, posts):
        for post in posts:
            text = f"{post.get('title', '')} {post.get('selftext', '')}"
            score, label = analyze_sentiment(text)
            post['sentiment_score'] = score
            post['sentiment_label'] = label
        return posts

Deduplicator

여러 스크래핑 세션에서 중복으로 나타날 수 있는 게시물을 제거합니다.

Keyword Extractor

스크랩된 콘텐츠에서 가장 중요한 용어를 추출해 트렌드 분석에 활용합니다.

Creating Your Own Plugin

plugins/ 디렉터리에 새로운 파이썬 파일을 추가합니다.

from plugins import Plugin

class MyCustomPlugin(Plugin):
    name = "my_plugin"
    description = "Does something cool"
    enabled = True

    def process_posts(self, posts):
        # Your logic here
        return posts

스크래핑 시 플러그인을 활성화합니다.

python main.py --mode full --plugins sentiment_tagger,deduplicator

REST API for External Integrations

API 서버 실행:

python main.py --api
  • API 기본 URL:
  • Documentation:

Key Endpoints

EndpointDescription
GET /posts필터(서브레딧, 제한, 오프셋)와 함께 게시물 목록
GET /comments댓글 목록
GET /subreddits스크랩된 모든 서브레딧
GET /jobs작업 이력
GET /query?sql=...파워 유저를 위한 원시 SQL 쿼리
GET /grafana/queryGrafana 호환 시계열 데이터

Real‑World Integration: Grafana Dashboard

  1. Grafana에 JSON API 또는 Infinity 플러그인을 설치합니다.
  2. datasource를 위 URL에 연결합니다.
  3. /grafana/query 엔드포인트를 시계열 패널에 사용합니다. 예시:
SELECT date(created_utc) AS time, COUNT(*) AS posts
FROM posts
GROUP BY date(created_utc);

이제 Reddit 활동을 실시간으로 추적하는 대시보드가 완성됩니다.

Scheduled Scraping & Notifications

Automation Made Easy

Cron‑스타일 스케줄링으로 정기 스크래핑을 설정합니다.

# 매 60분마다 스크랩
python main.py --schedule delhi --every 60

맞춤 옵션:

python main.py --schedule delhi --every 30 --mode full --limit 50

Get Notified

스크래핑이 완료되면 Discord 또는 Telegram 알림을 보낼 수 있도록 설정합니다.

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

스크래퍼가 선택한 플랫폼에 요약 알림을 전송합니다.

Dry Run Mode: Test Before You Commit

데이터를 실제로 저장하지 않고 스크래핑을 시뮬레이션합니다.

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

샘플 출력:

🧪 DRY RUN MODE - No data will be saved
🧪 DRY RUN COMPLETE!
📊 Would scrape: 100 posts
💬 Would fetch: 250 comments
Back to Blog

관련 글

더 보기 »