콘텐츠로 이동

4. TrendScraper 인터페이스를 통한 소스 확장 전략

  • 상태: 승인됨
  • 날짜: 2026-04-06

맥락

현재는 다음(Daum)만 수집하지만, 향후 네이버, 구글 트렌드 등 다른 소스를 추가할 계획이 있다. 소스마다 URL, 파싱 로직, 데이터 형태가 다르므로 확장 구조를 미리 설계해야 한다.

결정

TrendScraper 추상 클래스(ABC)를 정의하고, 각 소스는 이를 상속하여 구현한다.

class TrendScraper(ABC):
    @property
    def source_name(self) -> str: ...   # "DAUM", "NAVER"
    @property
    def base_url(self) -> str: ...      # 스크래핑 대상 URL
    def scrape(self) -> ScrapedResult: ...   # HTTP 수집
    def parse(self, raw_html: str) -> list[ScrapedKeyword]: ...  # HTML 파싱

근거

  • 단일 인터페이스: 파이프라인(TrendCollectPipeline)은 소스 구현체를 몰라도 된다. list[TrendScraper]를 순회하며 동일한 흐름(Scrape → Bronze → DB)을 실행한다.
  • 소스 추가 = 클래스 하나: 새 소스를 추가할 때 기존 코드를 수정할 필요 없이, 새 클래스를 만들고 main.py의 리스트에 등록하면 끝이다.
  • 테스트 용이: 각 스크래퍼의 parse() 메서드를 독립적으로 단위 테스트할 수 있다.

검토한 대안

대안 장점 선택하지 않은 이유
설정 파일 기반 (URL + CSS 선택자) 코드 없이 소스 추가 사이트마다 파싱 로직이 너무 달라 설정으로 표현 불가
Scrapy 프레임워크 기능 풍부 (미들웨어, 파이프라인) 현재 규모에서 과도, 단순 수집에 프레임워크 오버헤드 불필요
함수 기반 (scraper 함수 dict) 간결 소스 늘어나면 관리 어려움, 공통 인터페이스 강제 불가

결과

  • scraper/base.pyTrendScraper, ScrapedResult, ScrapedKeyword 정의.
  • 소스별 구현: scraper/daum.py (현재), 추후 scraper/naver.py 등.
  • main.pybuild_pipeline()에서 스크래퍼 리스트를 조합하여 파이프라인에 주입.