o2o-negosium-original/lps/services/search/st11/adapter.py
민헌 4b8dee8583 perf(lps): Step1 — 폴백 데드라인 + fail-fast로 검색 지연 상한
G마켓 챌린지가 안 풀린 채 25~70초를 먹던 문제에 상한을 씌운다. 폴백은 '있으면 좋은'
보강이라 데드라인으로 잘라도 안전(그 몰만 스킵).

- handler: 각 폴백 크롤에 fallback_deadline_sec(기본 15s) wait_for. 초과 시 스킵.
  _timed_search 예외를 BaseException 로(CancelledError 계측 포함).
- 폴백 어댑터 max_block_retries=0(챌린지 대기 2배 방지), ESM ready_timeout 22→12s, st11 20→15s.
- 테스트: 느린 폴백 데드라인 스킵 1종.

실측(동시성2·4상품): 상품당 p50 84.6s→34.2s(~2.5x), 벽시계 181s→65s(~2.8x),
처리량 1.3→3.7 상품/분, 1000건 $7.12→$5.06(~29%↓, 실패 챌린지 대역폭 절감).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 17:01:09 +09:00

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 = 15000
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)