한 검색의 소요·DECODO 비용을 크게 낮춘다(실측: 110s→52s, proxy 8MB→2MB, 총비용 70%↓). - 폴백 병렬화: _enrich_with_fallback 의 순차 for-loop → gather 동시 크롤. 각 몰 어댑터는 별 브라우저 인스턴스라 병렬 안전. 소요=합→최댓값. AI usage 계측 동시성 불변식 주석 명시 (judge.last_usage 세팅~읽기 사이 await 없음 → asyncio 협조 스케줄링상 안전). - 대역폭: blocked_resource_types 를 어댑터별 설정화. 오픈마켓은 이미지/미디어/폰트만 차단 (CSS/JS 유지 — 챌린지/렌더 보호). 격리 실험으로 차단 유무가 ESM 챌린지 성패에 무관함 확인 (실패 원인은 IP평판/headless). st11 라이브 0.11MB 검증. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
32 lines
1.4 KiB
Python
32 lines
1.4 KiB
Python
"""11번가 검색 어댑터 — 네이버 폴백용(네이버에 11번가가 없을 때만 크롤).
|
|
|
|
공식 오픈API 는 판매자 계정 필요라 불가 → PC 웹(search.11st.co.kr) 크롤.
|
|
챌린지 없이 렌더되므로 ready_selector(카드) 대기만으로 충분하다.
|
|
"""
|
|
|
|
from urllib.parse import quote
|
|
|
|
from services.search.browser_base import BrowserSearchAdapter
|
|
from services.search.contract import NormalizedProduct
|
|
from services.search.card_parser import parse_cards
|
|
from services.search.st11.selectors import SEARCH_URL, READY_SELECTOR, CARDS
|
|
|
|
_BLOCK_MARKERS = ("captcha", "robot", "비정상적인 접근", "errors.edgesuite.net")
|
|
|
|
|
|
class ElevenStAdapter(BrowserSearchAdapter):
|
|
source = "st11"
|
|
block_markers = _BLOCK_MARKERS
|
|
min_result_html = 20000 # PC 정상 결과는 수백 KB — 차단/미렌더 페이지는 작다(→회전/재시도)
|
|
ready_selector = READY_SELECTOR
|
|
ready_timeout_ms = 20000
|
|
block_resources_default = True # 라우팅 on — 이미지/미디어/폰트만(CSS/JS 유지해야 렌더됨)
|
|
blocked_resource_types = {"image", "media", "font"}
|
|
scroll_steps = 3 # 결과가 지연 로딩 → 스크롤로 트리거
|
|
|
|
def _search_url(self, query: str, limit: int) -> str:
|
|
return SEARCH_URL.format(q=quote(query))
|
|
|
|
def _parse(self, html: str) -> list[NormalizedProduct]:
|
|
return parse_cards(html, CARDS)
|