2026-07-10 협의: 검색은 네이버+쿠팡만. G마켓·옥션·11번가 폴백은 최종 최저가 기여 0회에 검색당 최대 15s·프록시 비용 ~87%를 차지해 로직에서 제외. 주석처리 대신 env 토글로 코드·테스트는 살려둔다(부패 방지·env 한 줄 재가동). - worker_main: LPS_FALLBACKS(기본 빈값=OFF)로만 폴백 어댑터 생성, 잘못된 값 경고, 기동 로그에 폴백 상태 표기. 핸들러는 빈 폴백을 원래 정상 처리라 로직 변경 없음 - run_local_worker.sh: 폴백 여부 대화형 질문 추가(기본 비활성) - compose: LPS_FALLBACKS 주석 env(재가동용) - decision-openmarket-crawler.md: 결정(B)·근거·재가동 절차(라이브 스모크 선행) 확정 기록 - README·architecture·operations: 기본 비활성 반영 검증: 전체 테스트 106 passed(폴백 로직 테스트는 fake 주입이라 계속 유효), 워커 실기동 로그 '오픈마켓 폴백: OFF' 확인 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
69 lines
5.0 KiB
Markdown
69 lines
5.0 KiB
Markdown
# 논의: 오픈마켓 크롤러를 계속 안고 갈까?
|
||
|
||
> 상태: **결정 완료(B. 게이트/OFF)** · 작성 2026-07-09 · 결정 2026-07-10 · 대상: 개발팀
|
||
> 한 줄: G마켓·옥션·11번가 **크롤러가 비용·복잡성의 ~80%인데, 실제 값어치(ROI)가 미증명**이라 유지 여부를 정해야 함.
|
||
|
||
---
|
||
|
||
## 1. 배경
|
||
|
||
LPS는 상품별 최저가를 찾는다. 소스는 2계층:
|
||
- **핵심**: 네이버 쇼핑 API(무료·빠름·안정) + 쿠팡(브라우저 크롤)
|
||
- **폴백**: 네이버가 못 덮은 몰만 **G마켓·옥션·11번가 크롤** → 몰별 가격
|
||
|
||
폴백 크롤러는 안티봇(쿠팡 Akamai, **G마켓/옥션 Cloudflare Turnstile**)을 뚫어야 해서 실제 브라우저 + residential 프록시(DECODO)가 필요하다.
|
||
|
||
## 2. 현재 데이터 (실측 2026-07)
|
||
|
||
| 항목 | 값 |
|
||
|------|-----|
|
||
| 검색 1건 비용 | **~$0.013** (1,000건 ~$13) |
|
||
| 그 중 DECODO(프록시 대역폭) | **~87%** ← 대부분 오픈마켓 크롤 |
|
||
| 크롤 몰이 **최종 최저가를 이긴 횟수** | **0** (네이버/쿠팡이 이김) |
|
||
| 상품당 지연 | ~35초 (크롤 때문) |
|
||
| gmarket 커버리지 | **IP 평판 의존, 플래키** (Turnstile) |
|
||
|
||
> 즉 **가장 비싸고·느리고·불안정한 부분이 최종 답을 바꾼 적이 없다.**
|
||
|
||
## 3. 크롤러가 주는 가치 (2가지)
|
||
|
||
1. **더 싼 가격 발견** — 데이터상 거의 없음(네이버/쿠팡이 최저가)
|
||
2. **몰별 검증·분석** — 네이버 보고가 vs 실제 크롤가 일치 확인, 몰별 투명성
|
||
→ **진짜 가치는 여기.** 단, **이 데이터를 실제로 소비하는 화면/의사결정이 있어야 의미**가 있음.
|
||
|
||
## 4. 핵심 질문 (팀 논의)
|
||
|
||
- ❓ **by_mall(몰별 가격) 데이터를 지금 또는 로드맵에서 실제로 쓰는 화면/기능이 있는가?**
|
||
- 있다 → 유지 가치 있음 (아래 A)
|
||
- 없다 / 막연히 쌓는 중 → 투기적. 소비자 생길 때 켜도 됨 (아래 B)
|
||
- ❓ 몰별 검증이 필요하다면 **얼마나 신선해야 하나?** (실시간? 1시간? 하루?)
|
||
- ❓ 비용 $13/1,000건 × 예상 검색량 = 월 얼마인가? 감당 범위인가?
|
||
|
||
## 5. 옵션
|
||
|
||
| 옵션 | 내용 | 비용/복잡성 | 언제 |
|
||
|------|------|------------|------|
|
||
| **A. 유지 + TTL 캐시** | 같은 상품 몰별 가격을 창(예 1h)당 1회만 크롤·재사용 | 비용 **대폭↓**(재크롤 회피율만큼), 구현 소(小) | by_mall 소비자가 있고, 분석 가치를 저렴히 유지하고 싶을 때 ← **추천** |
|
||
| **B. 게이트/OFF** | 크롤 기본 끔. 네이버 몰별분해(추가요청 0)만 사용. 필요 시 플래그로 켬 | 비용 **~87%↓**, 복잡성↓ | 아직 소비자가 없을 때 |
|
||
| **C. gmarket만 드롭** | 가장 플래키·비싼 gmarket 제거, 옥션·11번가 유지 | 부분 절감 | gmarket 부담만 클 때 |
|
||
| **D. 현행 유지** | 매 검색 전 몰 크롤 | 비용·불안정 그대로 | 분석 가치가 풀 비용을 정당화할 때 |
|
||
|
||
> **왜 curl_cffi(브라우저 없이 쿠키 재사용)로 싸게 못 하나?** 스파이크 결과 쿠팡(Akamai)은 되지만 **G마켓/옥션(Cloudflare)은 cf_clearance가 브라우저 지문에 고정돼 실패**. 즉 비싼 소스는 "크롤을 싸게"가 불가 → 남은 레버는 **"크롤을 덜 하기"(TTL 캐시)**.
|
||
|
||
## 6. 참고: 안 바뀌는 것 (크롤러와 무관하게 견고)
|
||
|
||
큐(PG 원자적 claim·lease·dead-letter), 어댑터 패턴, AI 같은상품 매칭, 비용 계측(CDP 실측), 다중 병렬, **네이버+쿠팡 핵심 경로**(싸고 빠르고 안정) — 여기는 유지. 이번 결정은 **오픈마켓 크롤러 서브시스템에 한정**된다.
|
||
|
||
---
|
||
|
||
## 결론 (2026-07-10 개발자 협의로 확정)
|
||
|
||
- [x] **결정: B. 게이트/OFF** — 검색은 **네이버+쿠팡만**. 오픈마켓 폴백 3종은 **코드·테스트 유지, 로직에서 제외(기본 비활성)**.
|
||
- 근거: 크롤 몰의 최종 최저가 기여 0회 + 검색당 최대 15s(폴백 데드라인) + 비용의 ~87%(DECODO)가 이 경로.
|
||
- [x] 구현: 주석처리가 아닌 **env 토글** — `LPS_FALLBACKS`(기본 빈값=OFF, 예: `gmarket,auction,st11`, 일부만도 가능).
|
||
- `worker_main.py` 가 이 값으로만 폴백 어댑터를 생성. 핸들러는 빈 폴백을 원래 정상 처리(`worker/handlers.py`)라 로직 변경 없음.
|
||
- 폴백 로직·파서 테스트는 fake 주입이라 **비활성 상태에서도 계속 돈다**(코드 부패 방지).
|
||
- by_mall 은 네이버 노출 몰 + 쿠팡으로만 채워짐 → 소비처(프론트) 연동 시 공유할 것.
|
||
- [x] 재개 트리거: by_mall 소비 화면이 생기거나, 특정 몰이 네이버 커버리지에서 빠져 가격 검증이 필요해질 때.
|
||
- **재가동 절차**: ① 라이브 스모크로 셀렉터 드리프트 점검(`LPS_LIVE=1 pytest tests/test_browser_base.py::test_live_smoke` + 대상 몰 1회 검색) → ② `LPS_FALLBACKS` 설정(로컬은 `run_local_worker.sh` 질문, 배포는 compose env) → ③ 웜업/차단 로그 확인. 미사용 기간 동안 셀렉터는 낡는다고 가정할 것.
|