본문으로 건너뛰기

JunkBox libs/shared-crawler 가이드

1. 라이브러리 역할

  • shared-crawler는 JunkBox 앱들이 공통으로 사용하는 웹 수집 보조 라이브러리임.
  • HTTP 기반 문서 수집, HTML 파싱 유틸, 선택적 Playwright 브라우저 세션 래퍼를 제공함.
  • 사이트별 로그인, selector, 데이터 매핑 같은 도메인 로직은 각 앱 또는 서비스가 소유함.
  • 공통화 대상은 브라우저 실행/컨텍스트 생성, 공통 요청 헤더, HTML selector 파싱 같은 반복 인프라 코드임.

2. 의존성 원칙

  • shared-crawler 자체는 Playwright를 필수 의존성으로 갖지 않음.
  • Playwright가 필요한 소비 앱이 자기 pyproject.tomlplaywright를 직접 선언함.
  • 따라서 HTTP 수집만 필요한 앱은 브라우저 런타임과 Chromium 설치 부담을 갖지 않음.
  • hub-api 대시보드는 HTTP/API 기반 수집을 우선 사용하고, 브라우저 크롤링은 꼭 필요한 대상이 생길 때만 별도 활성화함.

3. 패키지 구조

junkbox_shared_crawler/
├── browser.py
├── html.py
├── http.py
└── py.typed

4. 공개 기능

4.1 HTTP 수집

  • AsyncHttpCrawlerClient는 공통 User-Agent, Accept, Accept-Language 헤더와 timeout을 적용함.
  • fetch_text(url)은 redirect를 따라가고 HTTP 오류는 호출자에게 예외로 전달함.
  • 응답은 HttpFetchResult로 반환하며 url, status_code, text, content_type을 포함함.

4.2 HTML 파싱

  • HtmlDocument는 BeautifulSoup 기반 HTML selector 파싱 유틸임.
  • select(selector)Tag 목록을 반환함.
  • select_text(selector)는 첫 번째 selector 결과의 텍스트를 정규화해 반환함.
  • HtmlDocument.attr(tag, name)은 속성 값을 문자열로 정규화함.

4.3 Playwright 브라우저 세션

  • PlaywrightBrowserSession은 Playwright 실행, Chromium launch, context/page 생성, 종료를 담당함.
  • BrowserSessionOptions는 headless, locale, viewport, user_agent, launch_args를 정의함.
  • Playwright가 설치되지 않은 앱에서 브라우저 세션을 사용하면 명시적 런타임 오류를 발생시킴.

5. 소비 앱 기준

  • rename-api는 ASITE 로그인과 품번 검색 도메인 로직은 앱 내부에 유지하고, 브라우저 세션 생성만 shared-crawler를 사용함.
  • hub-api 대시보드는 wmania, 네이버 스포츠, 네이버 금융, FunETF처럼 HTTP/API로 충분한 대상은 Playwright 없이 수집함.
  • Glances API처럼 JSON API가 있는 대상은 웹 크롤링이 아니라 직접 HTTP API 호출로 처리함.

6. 운영 원칙

  • 외부 사이트는 selector, API path, 응답 스키마가 바뀔 수 있으므로 수집 실패를 정상적인 카드 상태로 표현해야 함.
  • 크롤링 결과가 사용자에게 표시되는 화면에서는 마지막 갱신 시각과 오류 메시지를 함께 제공함.
  • 인증 정보가 필요한 사이트는 각 앱 설정 계층에서 비밀값을 관리하고, shared-crawler는 비밀값 저장 책임을 갖지 않음.
  • 브라우저 크롤링은 실행 비용과 차단 가능성이 있으므로 HTTP/API 방식으로 해결 가능한 대상에는 사용하지 않음.

7. 관련 문서

  • 공통 설정 구조는 docs/junkbox/libs/guide-lib-shared-core.md를 따름.
  • hub 대시보드 구조는 docs/junkbox/apps/guide-apps-hub-api.md, docs/junkbox/apps/guide-apps-hub-ui.md를 따름.
  • Rename 수집 구조는 docs/junkbox/apps/guide-apps-rename-api.md를 따름.