fix(lps): gmarket 웜업 신뢰성 — 나쁜 IP 시 회전 재시도

웜업이 인터랙티브 Turnstile(IP 평판 나쁨)로 실패하면 다른 IP 로 회전해 최대 3회 재시도.
gmarket 커버리지 플래키함 완화(100 IP 풀에서 좋은 IP 를 찾을 확률↑).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
민헌 2026-07-09 21:06:29 +09:00
parent 0cd817a61d
commit 77a36c43d4

View File

@ -65,17 +65,23 @@ def _build_worker(i: int, concurrency: int, has_openai: bool, neg_cache, history
return handler, list(adapters.values()) + list(fallback_adapters.values())
async def _warmup_worker(worker_adapters):
"""워커의 챌린지 소스(Turnstile/Akamai)를 미리 1회 풀어 쿠키(cf_clearance 등)를 확보한다.
콜드 비용을 시작 시 1회로 몰아, 이후 실 작업은 웜(빠름). 백그라운드로 돌려 잡 처리를 막지 않는다."""
async def _warmup_worker(worker_adapters, tries: int = 3):
"""워커의 챌린지 소스(Turnstile/Akamai)를 미리 풀어 쿠키(cf_clearance 등)를 확보한다.
콜드 비용을 시작 시 몰아, 이후 실 작업은 웜(빠름). 백그라운드로 돌려 잡 처리를 막지 않는다.
나쁜 IP 는 인터랙티브 Turnstile 로 에스컬레이션되므로, 실패 시 **다른 IP 로 회전 재시도**한다."""
for ad in worker_adapters:
if ad.source not in ("gmarket", "auction", "coupang"):
continue
try:
await ad.search("생수", limit=1)
LOG.i(f"[warmup:{ad.source}] 챌린지 통과·쿠키 확보")
except Exception as ex:
LOG.w(f"[warmup:{ad.source}] 실패(무시, 첫 잡에서 재시도): {type(ex).__name__}")
for attempt in range(tries):
try:
await ad.search("생수", limit=1)
LOG.i(f"[warmup:{ad.source}] 챌린지 통과·쿠키 확보 (시도 {attempt + 1})")
break
except Exception as ex:
if attempt < tries - 1:
ad._rotate_ip(f"웜업 재시도({type(ex).__name__}) — 새 IP")
else:
LOG.w(f"[warmup:{ad.source}] {tries}회 실패(첫 잡에서 재시도): {type(ex).__name__}")
async def run_browser_reaper(adapters, stop, idle_sec: float = 120.0, interval: float = 30.0):