fix(tradein/cian): 403 снимает узел с выдачи, а не гаснет в return None (#2700) #2821

Merged
bot-backend merged 2 commits from fix/2700-cian-detail-403 into main 2026-08-10 11:29:19 +00:00

2 commits

Author SHA1 Message Date
bot-backend
7acefc0c9d fix(tradein/cian): ad-hoc ручка detail отвечает 502 на блок узла, а не 500 (#2700)
All checks were successful
CI / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 9s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m1s
Побочный эффект предыдущего коммита: 403 стал исключением, и POST /scrape/cian-detail
уронил бы его наружу необработанным. «Страницу не разобрали» (404) и «нас не пустили
с этого узла» (502) — разные новости для того, кто дёргает ручку руками.

Refs #2700
2026-08-10 16:19:55 +05:00
bot-backend
51a53cd173 fix(tradein/cian): 403 снимает узел с выдачи, а не гаснет в return None (#2700)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 3m57s
Различающая проба на проде 10.08: один и тот же detail-URL, один и тот же код,
менялся ТОЛЬКО прокси-узел. Узел 1 — HTTP 403, 21 564 байта, маркер
`cian_waf_block`; узлы 9/10/11 — HTTP 200, ~617 КБ, состояние разбирается. Отбита
пара «узел × Циан», а не площадка: те же 200 пришли без единой куки — detail-
страница авторизации не требует, и к протухшим 30.06 кукам эти 403 отношения не
имели.

Держалось это пятнадцать суток потому, что 403 умирал внутри провайдера в
`return None`: наружу не выходило ничего, пул получал mark_health(ok=True) на
отбитый узел и продолжал выдавать его Циану, а прогон писал detail_failed=50 при
errors_count=0 и статусе done.

- providers/cian/detail.py: 403 → CianBlockedError (наследник ProxyBanError, как
  AvitoBlockedError/DomClickBlockedError). Generic curl-слой сам делает
  mark_banned на пару «узел × cian», оба вызывающих в pipeline уже считают
  исключение в errors_count. 404 (снятое объявление) баном не считается.
- scrape_runs.mark_done (обе копии): прогон, у которого отказала КАЖДАЯ попытка
  целой фазы (>=3 попыток), больше не done. Пары <phase>_attempted/<phase>_failed
  ищутся в самих counters, а не по зашитому списку фаз. Замер на проде за 90
  суток: 52 прогона из 3292 done (1.6%) — 33 cian_city_sweep*, 11 avito_city_sweep*.

Тест красный на старом коде в трёх утверждениях: узел не банился, и оба
финализатора писали 'done' прогону 3258 (detail 50/50 отказ).

Refs #2700
2026-08-10 16:13:12 +05:00