fix(scraper-kit/cian): фаза houses cian_city_sweep через пул прокси + стоп на пустом пуле (#3394) #3396
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3396
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/3394-cian-sweep-houses-proxy-pool"
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?
Closes #3394.
Дефект.
run_cian_city_sweep, фаза houses (orchestration/pipeline.py:3224):await fetch_newbuilding(zhk_url, config=config)безproxy_provider→ вproviders/cian/newbuilding.pyфетчер без пула →/fetchбезproxy→ сайдкар на env-фолбэкеSCRAPER_PROXY_URL(выключенный узел 9, 407) → camoufoxInvalidIP→ 503. Фаза работала 30/30 до 01.09 и падает целиком с 02.09 (смерть узла 9): run 6179 — 30/30 отказов, 24×Server error '503' for url 'http://tradein-browser:3000/fetch', в сайдкаре ни одной строки[cian] … override=True; за 04–06.09 Loki насчитал 4684 «503 браузер недоступен» по cian.Фикс (
pipeline.py):proxy_provider=proxy_providerв вызов (:3222-3234; тот же объект, что уже уходит вCianScraperиcian_fetch_detail);CianCitySweepCounters.no_proxy_stop: int(:2849,1— как у соседей); в houses-циклеif caused_by_no_proxy(exc): raise(:3243-3260, логhouses СТОП — пул прокси пуст); веткаexcept NoProxyAvailableErrorвокруг фаз якоря (:3336-3361, до generic) →no_proxy_stop=1, heartbeat +mark_banned(ban_kind=infra)сdone_buckets— иначе наш отказ инфраструктуры копилconsecutive_failuresи через 3 якоря превращался в «IP likely blocked».Аудит вызовов:
cian_history_backfill.py:352(RealProxyProvider, #3382),newbuilding_enrich_backfill.py:497/546,admin.py:2175(_kit_proxy_provider()) — провайдер передают; дыра была только в свипе.fetch_newbuilding/resolve_cian_zhk_url_via_searchNoProxyAvailableErrorнаружу пропускают (глотания, как у yandex в #3389, нет).Тесты
tests/test_3394_cian_sweep_houses_proxy_pool.py: через настоящийrun_cian_city_sweep → fetch_newbuilding → build_browser_fetcher, подделан толькоproviders._base.BrowserFetcher: фетчер строится сproxy_provider is provider; пустой пул → ровно один дом,no_proxy_stop=1.Фальсификация (
git apply -Rpipeline.py):assert None is <MagicMock proxy_provider>ивторой дом упрётся в то же самое: Left contains 2 more items(триhouses failedподряд в логе). Восстановлено.Прогоны: полный backend
5532 passed, 35 skipped(rc=0); ruff OK.Приёмка на проде: следующий
cian_city_sweep(~03:30 UTC 07.09) —houses_enriched > 0приhouses_attempted > 0, в сайдкаре[cian] … override=Trueпо newbuilding-страницам (с 02.09 не было ни одной),InvalidIPдля cian = 0; при реально пустом пуле — ровно одинhouses failed,houses СТОП — пул прокси пуст,banned+no_proxy_stop=1.Code-review (06.09): minor, блокеров нет. Подтверждено: порядок
except(TimeoutError → NoProxyAvailableError → generic; логика «IP likely blocked» только в timeout/generic);mark_banned(ban_kind=infra)— локальный прецедент в этом же файле (cian full-load:3788, avito:4071/:4342,:4632), стрик failed/banned не различает статусы;done_bucketsдоезжают черезmark_banned,banned∈_RESUME_STATUSES;no_proxy_stopуезжает1; тесты через настоящийrun_cian_city_sweep → fetch_newbuilding → build_browser_fetcher.Докатываю до мержа: (1) raise-site решает по цепочке причин, а catch-site на уровне якоря ловит только голый
NoProxyAvailableError— как толькоfetch_newbuildingначнёт оборачивать исключение (какfetch_detail), стоп уйдёт в generic → «IP likely blocked» безno_proxy_stop; ловлю поcaused_by_no_proxyна уровне якоря + тест с обёрнутым исключением; (2)errors_countдважды на одно событие; (3) комментарий про «лоте» — detail-фаза глотает; (4) ассертыuse_pool/environmentне различают эпохи,ban_kind='infra'без покрытия — исправляю.