fix(scrapers): разблокировать domrf_kn flats — изоляция flats от poison-extras + throttle (#1945) #2050
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2050
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/kn-loader-throttle-proxy-1945"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Закрывает #1945 (domrf_kn FLATS loader сломан DOM.РФ WAF, flats_count=9 vs ~376k, 5+ нед). code-reviewer ✅ APPROVE. Прод-проба доказывает unblock.
Корень (переаттрибуция — НЕ то, что думали)
Loader УЖЕ гоняет headless Playwright (browser-fetch есть). Бан session/cookie-scoped, НЕ IP (свежая сессия → flats=200). Реальный яд: extras-семейство (
/сервисы/api/object/{id}/*) 403-ит сразу (без объёма) и травит cookies сессии → последующие flats на той же сессии → 403. Flats-эндпоинт (/portal-kn/api/sales/portal/table) сам по себе чист. Extras — supplementary и уже мертвы (sale_graph/sales_agg/infra/photos/docs → 0 строк неделями); flats_count приходит ТОЛЬКО из flats-эндпоинта.Фикс
extras_isolated=True, дефолт): warm-сессия делает ТОЛЬКО flats (extras на ней не вызываются → яд не достаёт flats); extras — отдельным best-effort проходом в disposable-сессиях, recycle при WAF-403, early-abort после 5 подряд all-WAF (extras сейчас wholesale-403 → не молотить ~1500 релончей). Best-effort: любой сбой extras логируется, НЕ роняет run/flats (flats закоммичены до extras-прохода).concurrency(KN-sweep дефолт 2 vs модульный 8 — не тронут для catalog/nspd) + конфиг-jitter.parse_proxy_url+ Playwrightlaunch/context proxy=(default off; main worker без proxy-env → next-lever для devops, креды только в tradein-scraper). Creds НЕ логируются (фикс утечки в ValueError).extras_isolated=Falseсохраняет старый combined-путь (rollback).Прод-проба (реальный тест)
250 объектов через изолированный flats-путь (concurrency 2, без proxy):
ok=237, waf_403=0, flat_rows=77163(404=13 легит). Vs сломанное run 32 = 9 flats / 1548 объектов. 0 яда на 251 запросе → sweep восстанавливает flats_count ≫ 9 (исторический ~3670+ ЖК).Качество
:name::type; SAVEPOINT per-row соблюдён; 548 passed (+22 теста: throttle/proxy/изоляция/creds-no-leak). pre-commit чисто.Деплой → flats восстановятся на следующем scrape_kn (cron); #1948-монитор подтвердит (kn_flats снимет
failed). Closes #1945.DOM.РФ WAF банит на full sweep (~17k req @ concurrency=8): сессия, тронувшая gated /сервисы/api/object/* extras, получает 403 → cookies сессии флагуются → последующие запросы (incl. flats) тоже 403. Эмпирически (prod worker, throttle@concurrency=2, без прокси): • flats-only, 100 объектов / 104 req — 0 WAF-бан; • mixed flats+extras — extras 403 сразу, затем травит сессию (flats→403). Значит throttle снижает rate, но НЕ устраняет session-poisoning от extras; прокси (mobile-proxy, как в tradein) — следующий рычаг, off-by-default. - config: scrape_kn_browser_concurrency=2, scrape_kn_request_jitter_{min,max}_ms, scrape_kn_proxy_url=None (прокси опционален, дефолт — прямое подключение). - stealth.BrowserSession: per-instance concurrency / jitter / proxy_url; parse_proxy_url(http://user:pass@host:port → Playwright proxy-dict). Модульный _BROWSER_CONCURRENCY=8 не тронут — catalog/nspd без изменений. - domrf_kn.run_region_sweep + workers/tasks/scrape_kn: прокидывают новые settings ТОЛЬКО в KN-sweep BrowserSession. - tests: parse_proxy_url, threading concurrency/jitter/proxy, defaults unchanged.ГЛАВНЫЙ unblock. Эмпирически (prod worker): • flats endpoint /portal-kn/api/sales/portal/table @ concurrency=2 — 0 WAF-бан на 250 объектах / 251 req, 77163 flat-строк (vs текущие 9 во всём sweep); • extras /сервисы/api/object/{id}/* отдают 403 СРАЗУ (volume-independent, мертвы с 2026-06-03) И травят cookies сессии → последующие flats на ней тоже 403. flats_count рухнул 3670→9 именно из-за shared-session отравления. Fix: flats и extras больше НИКОГДА не делят сессию. - run_region_sweep(extras_isolated=True, дефолт): warm flats-сессия тянет ТОЛЬКО flats (extras на ней не вызываются) → flats_count восстанавливается; extras уходят отдельным best-effort проходом _run_extras_pass с recycle BrowserSession на каждый WAF-403 (яд не накапливается, flats-сессия уже закрыта). - _run_extras_pass: ранний обрыв после N подряд полностью-WAF объектов (_EXTRAS_ABORT_AFTER_CONSEC_WAF=5) — extras мертвы целиком, нет смысла жечь ~1500 релончей браузера. Любой сбой паса → log, run НЕ падает. - extras_isolated=False → старое combined-поведение (poison-prone). - config: scrape_kn_extras_isolated=True (ENV SCRAPE_KN_EXTRAS_ISOLATED); прокинут через оба worker call-site. - рефактор: _process_flats_result / _process_extras_result / _extras_coros делят upsert-логику между combined-loop и isolated-pass. - tests: _extras_coros без flats, _is_waf_poisoned, recycle-на-poison, early-abort на wholesale-WAF. Сохраняет throttle + optional-proxy из предыдущего коммита.parse_proxy_url raised ValueError(f"...{proxy_url!r}") embedding the FULL proxy URL incl. password. Это исключение всплывает в run_region_sweep try → пишется в kn_scrape_runs.error (str(e)[:2000]) + log_progress + logger.exception→Sentry — малформный proxy URL утёк бы пароль. Теперь сообщение содержит только scheme, без сырого URL/creds. Happy-path лог уже server-only (host:port), creds не пишет. test: ValueError-сообщение НЕ содержит пароль/юзера/сырой URL.