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.py에TrendScraper,ScrapedResult,ScrapedKeyword정의.- 소스별 구현:
scraper/daum.py(현재), 추후scraper/naver.py등. main.py의build_pipeline()에서 스크래퍼 리스트를 조합하여 파이프라인에 주입.