9.1 KiB
Ontology Crawler Platform
향수 구독 플랫폼을 첫 사용 사례로 삼되, 차, 커피, 캔들, 디퓨저, 영양제, 선물, 패션 소품 같은 개인화 구독 추천 서비스에 재사용할 수 있는 범용 크롤러/온톨로지 기반 지식 DB MVP입니다.
핵심 아이디어
이 시스템은 웹에서 가져온 문장을 곧바로 사실로 저장하지 않습니다. 모든 정보는 Claim으로 저장됩니다.
subject: Product A
predicate: hasTopNote
object: Bergamot
source: OfficialSite
evidence_text: Top notes: Bergamot, Neroli
confidence: 0.95
추천 시스템은 원문 복제가 아니라, 출처, 근거, 신뢰도, 갱신일을 가진 온톨로지 매핑 지식을 사용합니다.
아키텍처
flowchart LR
A["URL Discovery"] --> B["Page Fetch"]
B --> C["HTML Clean"]
C --> D["Site Parser Plugin"]
D --> E["Extractor Provider"]
E --> F["Ontology Mapping"]
F --> G["Deduplication"]
G --> H["Confidence Scoring"]
H --> I["Knowledge DB"]
I --> J["Recommendation API"]
I --> K["Update Scheduling"]
구성 단위:
Project: 향수 구독, 차 구독, 선물 추천 같은 프로젝트 단위 설정Source: 공식몰, 마켓플레이스, 리뷰 사이트 같은 데이터 출처Page: 수집된 URL과 정제 텍스트 요약Entity: 상품, 브랜드, 노트, 무드, 계절, 상황 등 의미 객체Claim: 출처가 주장한 정보 단위Evidence: Claim의 근거 문장Relation: Entity 간 집계 관계ExtractionLog: 추출 방식, Provider, 로그
폴더 구조
crawler_platform/
app/
main.py
config/
core/
crawler/
extractor/
ontology/
database/
recommendation/
scheduler/
domains/
perfume/
tea/
coffee/
candle/
supplement/
gift/
api/
cli/
configs/
perfume_subscription.yaml
tests/
README.md
DB 스키마
초기 MVP는 SQLAlchemy ORM으로 SQLite와 PostgreSQL을 모두 지원합니다.
필수 테이블:
projects: 프로젝트 이름, 도메인, JSON 설정sources: 출처 타입, 신뢰도, robots 정책, rate limitpages: URL, fetch 상태, content hash, 정제 텍스트 요약entities: 범용 의미 객체attributes: Entity 속성relations: Entity 간 집계 관계claims: 출처가 주장한 subject-predicate-object 정보evidence: Claim 근거 텍스트extraction_logs: 추출 Provider와 로그crawl_jobs: 예약 수집 작업user_profiles: 추천 사용자user_preferences: 취향 구조feedback_logs: 추천 피드백
설치
pip install -r requirements.txt
playwright install chromium
정적 페이지는 requests + BeautifulSoup로 처리합니다. 동적 페이지가 필요하면 config에서 fetcher: playwright로 바꾸면 됩니다.
CLI 사용
DB 초기화:
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db init-db
향수 프로젝트 생성:
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db create-project --config configs/perfume_subscription.yaml
온톨로지 조회:
python -m crawler_platform.app.cli.main ontology --domain perfume
단일 URL 수집:
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db crawl-url \
--config configs/perfume_subscription.yaml \
--source official_brand_site \
--url https://example.com/perfume/product-page
네트워크 없이 로컬 샘플 HTML로 파이프라인을 확인할 수도 있습니다.
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db crawl-url \
--config configs/perfume_subscription.yaml \
--source official_brand_site \
--url tests/fixtures/sample_perfume.html
분석기 Provider를 바꿀 수도 있습니다. 기본값은 규칙 기반이며, AI Provider는 모델/API 키 또는 로컬 서버 설정이 필요합니다.
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db crawl-url \
--config configs/perfume_subscription.yaml \
--source official_brand_site \
--url tests/fixtures/sample_perfume.html \
--extractor-provider ollama \
--extractor-model llama3.1
지원 Provider:
rule_based: 정규식/키워드 기반 기본 분석기openai: OpenAI 호환 Chat Completions API,OPENAI_API_KEY와 모델 필요ollama: 로컬 Ollama, 기본 URLhttp://localhost:11434/api/chatlm_studio: LM Studio OpenAI 호환 서버, 기본 URLhttp://localhost:1234/v1/chat/completions
LM Studio 사용 순서:
- LM Studio에서
Developer또는 Local Server 화면을 엽니다. - OpenAI Compatible Server를 켭니다.
- 서버 주소가 보통
http://localhost:1234/v1인지 확인합니다. - 웹 UI의 Analyzer에서
LM Studio를 선택합니다. - Base URL은 비워두거나
http://localhost:1234/v1을 넣습니다. 연결 테스트로 모델 목록을 불러옵니다.- 모델이 자동 입력되면
수집 실행을 누릅니다.
Claim 확인:
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db claims --project perfume_subscription
추천 예시:
python -m crawler_platform.app.cli.main --db sqlite:///crawler_platform.db recommend \
--project perfume_subscription \
--target-type Perfume \
--preferences-json "{\"preferred_notes\":[\"Bergamot\",\"Musk\"],\"preferred_moods\":[\"Fresh\"],\"season_context\":\"Summer\"}"
FastAPI 실행
uvicorn crawler_platform.app.main:app --reload
브라우저에서 관리자 UI를 열 수 있습니다.
http://127.0.0.1:8000/
관리자 UI에서 가능한 작업:
- 프로젝트 config 경로로 프로젝트 생성
- Source 선택 후 URL 또는 로컬 HTML 샘플 수집
- 분석기 Provider 선택: Rule-based, OpenAI, Ollama, LM Studio
- 도메인 온톨로지, Entity, Claim 조회
- Claim 신뢰도와 사유 수동 수정
- Entity ID 기준 병합
- 추천용 태그 확인
- 사용자 취향 입력 후 추천 결과 테스트
주요 엔드포인트:
GET /healthGET /GET /projectsPOST /projectsGET /ontology/{domain}POST /crawlPOST /crawl-siteGET /projects/{project_name}/entitiesGET /projects/{project_name}/claimsPATCH /claims/{claim_id}/confidencePOST /entities/mergeGET /projects/{project_name}/recommendation-tagsPOST /recommend
사이트 순회 수집
단일 상품 URL뿐 아니라 Seed URL에서 시작해 같은 도메인의 링크를 따라가는 수집도 지원합니다.
Seed URL
→ robots 확인
→ 링크 추출
→ same-domain 필터
→ URL queue 저장
→ depth / max pages 제한
→ 각 페이지 fetch
→ 상품/브랜드/리뷰 페이지 판별
→ 분석
→ DB 저장
→ 다음 링크 반복
웹 UI에서는 Crawl site from seed를 사용합니다.
API 예시:
curl -X POST http://127.0.0.1:8000/crawl-site \
-H "Content-Type: application/json" \
-d '{
"config_path": "configs/perfume_subscription.yaml",
"source_name": "official_brand_site",
"url": "https://example-brand.com",
"extractor_provider": "rule_based",
"max_depth": 2,
"max_pages": 50,
"same_domain_only": true,
"analyze_page_types": ["product", "brand", "review"]
}'
주의: 검색 결과 페이지나 robots가 막는 페이지는 수집하지 않습니다. 그런 데이터는 공식 API Provider로 붙이는 방식이 맞습니다.
향수 도메인 MVP
기본 엔티티:
PerfumeBrandNoteAccordMoodSeasonOccasionReviewPriceProductPage
기본 관계:
hasBrandhasTopNotehasMiddleNotehasBaseNotehasAccordevokesMoodsuitableForSeasonsuitableForOccasionsimilarTosoldByhasPricehasReviewKeyword
규칙 기반 추출기는 Top notes, Middle notes, Base notes, 가격, 무드, 계절, 사용 상황, 리뷰 키워드를 우선 추출합니다.
확장 방법
새 도메인을 추가할 때는 다음을 추가하면 됩니다.
configs/{project}.yaml에domain,target_entities,fields,sources,ontology정의crawler_platform/app/core/ontology/definitions.py에 도메인 온톨로지 추가- 필요하면
crawler_platform/app/domains/{domain}/extractor.py에 도메인별 Extractor 구현 - 사이트별 HTML 구조가 특수하면
SiteParser를 구현하고ParserRegistry에 등록 - OpenAI, Ollama, LM Studio 등 AI 추출은
AIExtractor를 상속하는 Provider로 추가
컴플라이언스 설계
robots.txt확인 구조 포함- Source별 rate limit과 User-Agent 적용
- retry, timeout 고려
- 원문 전체 저장 대신
evidence_text와 정제 요약 중심 저장 - 상품 설명은 복제 저장보다 Claim, 태그, 요약, 근거 중심으로 사용
테스트
pytest
외부 테스트 러너가 없을 때는 기본 unittest 스모크 테스트를 실행할 수 있습니다.
python -m unittest tests.test_smoke_unittest -v
현재 테스트는 향수 규칙 기반 추출, config 로더, 로컬 HTML fetch 경로를 검증합니다.