3 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 224f91e8fa |
fix(cian): капча видна в отчёте прогона и банит узел на curl-пути (#3402)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m11s
Два follow-up из ревью #3403. 1. Капча-волна была невидима в счётчиках. `_note_refusal` ключевался только по HTTP-статусу, а капча приходит с 200 (свой детект по <title>) или без статуса (сайдкар) → рос один `listings_failed_fetch`, `ban_kinds` оставался пустым, и волна отказа площадки читалась как дрейф нашей разметки. Теперь диагноз берётся сперва по ТИПУ исключения (`ban_kind_of_exception`), статус — фолбэк. Инвариант #3196 сохранён: 'unknown' по типу И None по статусу по-прежнему ничего не пишут. `ban_kind_of_exception` расширен с `AvitoBlockedError` до `ProxyBanError` — это ровно тот mixin, по которому generic-прокси-слой уже снимает узел с выдачи источнику. Для Авито поведение не меняется (AvitoBlockedError его наследует), Cian/DomClick перестают приезжать как 'unknown'. 2. curl-путь детектил капчу, но не банил: общий parse-путь лежит ЗА границей `with curl_proxy_url(...)`, и `CianBlockedError` поднимался уже после `mark_health(ok=True)` — узел, которому Циан показывает капчу, оставался в выдаче Циану (дефект #2700, только на HTTP 200). Проверка перенесена ВНУТРЬ блока, `finally` хелпера сам делает `mark_banned(source='cian')`. Тесты по значению (оба красные на main): батч с капчей → ban_kinds == {platform: 1}; curl-путь + HTML капчи → mark_banned == [(1, 'cian')], mark_health(ok=True) нет. |
|||
| 957e9e8c01 |
fix(#3402): капча = «Captcha…» и «Вы не робот?» (бан+ротация); «Ошибка - Циан» — только лог на цикл наблюдения
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m8s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 1m27s
Ревью (⚠️ minor) на #3403: «Ошибка - Циан» может быть транзиентной 5xx-страницей, отданной с кодом 200, а не отказом конкретному узлу. Цена ошибки несимметрична — mark_banned эскалирует TTL до часов, поэтому 20-минутный сбой площадки выбил бы из выдачи весь пул. Один список маркеров этого различить не мог: и капча, и страница ошибки шли одним путём в BanPageDetectedError. Проба прода 06.09.2026 09:25 UTC (одна карточка по узлам через сайдкар): * узел 14, час назад отдававший «Captcha - база объявлений ЦИАН», вернул НАСТОЯЩУЮ карточку — капча снимается за 1-2 часа, то есть TTL бана по назначению; * узел 1 отдал ТРЕТИЙ вариант отказа — `<title>Вы не робот?`, 16 КБ (час назад — «Ошибка - Циан», 374 КБ). Прежние маркеры его не знали вовсе: отказ уезжал наверх как валидный HTML ровно так же, как до #3402. Маркеры разделены на два класса, одинаково в обоих слоях (образы backend и browser деплоятся раздельно и расходятся на часы): * КАПЧА — «captcha - база объявлений циан» + «вы не робот?»: безусловный отказ площадки, прежний путь (сайдкар → BanPageDetectedError → 403 + ban_page; kit → report_platform_ban + CianBlockedError). За ней нет контента, и узел, которому её показали, будет получать её дальше; * «ошибка - циан» — ТОЛЬКО ЛОГ: сайдкар отдаёт HTML клиенту как есть и пишет WARNING «страница ошибки Циана (title=…, upstream=…) — не бан, только лог (#3402)», kit при провале extract_state пишет WARNING и возвращает прежний None. Ни бана, ни рапорта, ни исключения — решение принимаем по частоте в логах за цикл наблюдения, а не по догадке о природе страницы. Нормализация заголовка прежняя (регистр/пробелы/тире). `_is_cian_refusal` → `_is_cian_captcha` + `_log_cian_error_page`; `_refusal_title` → `_page_title` и два кортежа маркеров рядом. Фальсификация: «вы не робот?» убран из маркеров обоих слоёв → kit 1 failed («DID NOT RAISE CianBlockedError»), сайдкар 3 failed («DID NOT RAISE BanPageDetectedError», `_is_cian_captcha` → assert False is True). Маркер возвращён, обе сьюты зелёные: backend 5599 passed / 35 skipped, browser 246 passed. |
|||
| ff979d4afd |
fix(tradein/cian): капча Циана с HTTP 200 — отказ площадки в обоих слоях (#3402)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 11s
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 / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 1m28s
CI Trade-In / backend-tests (pull_request) Successful in 5m11s
Циан отдаёт капчу (`<title>Captcha - база объявлений ЦИАН`, 44 КБ) и страницу
ошибки (`<title>Ошибка - Циан`, 374 КБ) с кодом 200. Детектор сайдкара их не знал
(_REFUSAL_STATUSES {403,429} + маркеры Авито/Домклика), HTML уезжал клиенту как
успех, extract_state возвращал None и провайдер печатал «defaultState extraction
failed» — отказ ПЛОЩАДКИ читался как дрейф НАШЕЙ разметки. Аренда при этом не
менялась: fetch() уже отрапортовал mark_health(ok=True), fail-streak обнулялся, и
один капча-узел сжигал батч целиком (6200: 0/210; 6123/6091/6052/6032/6010/5981:
0/400 — против 161/162 через здоровый узел на прогоне 13).
Два слоя, потому что образы backend и browser деплоятся раздельно и расходятся
на часы:
* сайдкар (browser/server.py) — детект по <title> на обоих путях (navigate и
подзапрос) → BanPageDetectedError → прежний путь #3288/#3379: 403 + ban_page +
ЧЕСТНЫЙ upstream-статус 200;
* kit (providers/cian/detail.py) — при провале extract_state те же маркеры →
CianBlockedError вместо тихого None, плюс report_platform_ban по живому lease.
Там же ветка SidecarBanPageError: отказ, опознанный сайдкаром, больше не
гасится общим `except` в «не смогли разобрать».
Слово `captcha` признаком быть не может: в нормальной карточке оно встречается 11
раз, на капче 17. Детект по <title> с нормализацией тире.
`_report_platform_ban` → `report_platform_ban` (публичный): тем же путём обязан
идти отказ, распознанный не сайдкаром, а провайдером. report_ban один только
пишет бан пары «узел×источник» — сменить сожжённую аренду ВНУТРИ батча позволяет
только fail-streak (_LEASE_ROTATE_AFTER_FAILS).
|