fix(tradein/domclick): 401 — тот же отказ площадки, что 403, а классифицировался как unknown (#3196) #3204

Merged
lekss361 merged 1 commit from fix/3196-domclick-401 into main 2026-08-29 09:27:36 +00:00
Owner

Дополняет #3202 (issue #3196). Без этой правки предыдущий PR чинит механизм, но не тот статус, который ДомКлик отдаёт в реальности.

Замер на проде (2026-08-29, боевой контейнер tradein-scraper)

После деплоя #3202 прогнал три карточки подряд через боевой путь — с сохранённой сессией и без:

1 BLOCKED  http= 401  ban_kind= None
2 BLOCKED  http= 401  ban_kind= None
3 BLOCKED  http= 401  ban_kind= None

Страница отказа при 401 — ровно 26 624 байта, байт в байт та же, что снималась 28.08 под кодом 403 | Домклик. Ни startpow, ни QRATOR, ни капчи. Приходит одинаково и с валидной сессией на 16 куков, и полностью анонимно — значит это не «сессия отвергнута» (тогда анонимный запрос вёл бы себя иначе), а WAF-отказ с подменённым кодом ответа.

В таблице классификатора 401 не было (403/429 → platform, 5xx → infra), поэтому ban_kind_from_status(401) вернул None, а _ban_kind_of_block подставил unknown — ровно то, что #3196 и должен был убрать.

Что радует отдельно

Механика диагноза оказалась полностью рабочей: статус доезжает от page.goto через сайдкар до .status исключения целым int. То есть шов providers/domclick/detail.py::fetch_detail (blocked.status = status), который в #3202 остался без теста и был отмечен там как известный пробел, теперь подтверждён живым 401 на проде.

Почему правка доменная, а не в общей функции

scraper_kit.browser_fetcher.ban_kind_from_status не тронута. У других поставщиков 401 обычно значит «наша сессия протухла» — это наша сторона, и общая метка platform там зря запустила бы ротацию IP (#2611). Исключение живёт в домкликовом таске, где обосновано замером.

Проверка

  • tradein-mvp/backend: 4972 passed, 37 skipped
  • ruff check чисто
  • В параметризацию существующего теста добавлен случай 401 → platform (новых тестов не заводил)

Смежное наблюдение (в этом PR не чинится)

Detail-путь ДомКлика обходит пул прокси (use_pool/proxy_provider — дефолты, #3197) и берёт статический SCRAPER_PROXY_URL. Сейчас он указывает на 190.2.145.131:10313 — это узел 9 asocks-mobile-1, у которого enabled = f, consecutive_fails = 7 и пустой exit_ip. То есть ДомКлик выходит через узел, который пул сам признал негодным, при живых включённых 10 и 11. Возможно, после #3197 эти 401 исчезнут сами.

Дополняет #3202 (issue #3196). Без этой правки предыдущий PR чинит механизм, но не тот статус, который ДомКлик отдаёт в реальности. ## Замер на проде (2026-08-29, боевой контейнер `tradein-scraper`) После деплоя #3202 прогнал три карточки подряд через боевой путь — с сохранённой сессией и без: ``` 1 BLOCKED http= 401 ban_kind= None 2 BLOCKED http= 401 ban_kind= None 3 BLOCKED http= 401 ban_kind= None ``` Страница отказа при 401 — **ровно 26 624 байта**, байт в байт та же, что снималась 28.08 под кодом `403 | Домклик`. Ни `startpow`, ни QRATOR, ни капчи. Приходит одинаково **и с валидной сессией на 16 куков, и полностью анонимно** — значит это не «сессия отвергнута» (тогда анонимный запрос вёл бы себя иначе), а WAF-отказ с подменённым кодом ответа. В таблице классификатора 401 не было (`403/429 → platform`, `5xx → infra`), поэтому `ban_kind_from_status(401)` вернул `None`, а `_ban_kind_of_block` подставил `unknown` — ровно то, что #3196 и должен был убрать. ## Что радует отдельно Механика диагноза оказалась полностью рабочей: статус доезжает от `page.goto` через сайдкар до `.status` исключения целым `int`. То есть шов `providers/domclick/detail.py::fetch_detail` (`blocked.status = status`), который в #3202 остался **без теста** и был отмечен там как известный пробел, теперь подтверждён живым 401 на проде. ## Почему правка доменная, а не в общей функции `scraper_kit.browser_fetcher.ban_kind_from_status` **не тронута**. У других поставщиков 401 обычно значит «наша сессия протухла» — это наша сторона, и общая метка `platform` там зря запустила бы ротацию IP (#2611). Исключение живёт в домкликовом таске, где обосновано замером. ## Проверка - `tradein-mvp/backend`: 4972 passed, 37 skipped - `ruff check` чисто - В параметризацию существующего теста добавлен случай `401 → platform` (новых тестов не заводил) ## Смежное наблюдение (в этом PR не чинится) Detail-путь ДомКлика обходит пул прокси (`use_pool`/`proxy_provider` — дефолты, #3197) и берёт статический `SCRAPER_PROXY_URL`. Сейчас он указывает на `190.2.145.131:10313` — это узел **9** `asocks-mobile-1`, у которого `enabled = f`, `consecutive_fails = 7` и пустой `exit_ip`. То есть ДомКлик выходит через узел, который пул сам признал негодным, при живых включённых 10 и 11. Возможно, после #3197 эти 401 исчезнут сами.
lekss361 added 1 commit 2026-08-29 09:20:26 +00:00
fix(tradein/domclick): отказ с кодом 401 классифицировался как причина неизвестной природы (#3196)
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 / changes (pull_request) Successful in 11s
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 / backend-tests (pull_request) Successful in 4m55s
663f426d4c
Замер на проде 2026-08-29: страница отказа ДомКлика при HTTP 401 — РОВНО
26 624 байта, байт в байт та же, что снималась 28.08 под кодом 403. Ни PoW,
ни QRATOR, ни капчи. Приходит одинаково и с валидной сохранённой сессией
(16 куков из domclick_session), и полностью анонимно — значит это не
«сессия отвергнута», а WAF-отказ с подменённым кодом ответа.

В таблице классификатора 401 не было (403/429 → platform, 5xx → infra),
поэтому все три пробы подряд дали ban_kind='unknown' — ровно то, что #3196
и должен был убрать. Механика диагноза при этом рабочая: статус доезжает от
page.goto до исключения целым, шов blocked.status = status подтверждён живым
401 на проде.

Правка доменная — в _ban_kind_of_block домкликового таска, а не в общей
scraper_kit.browser_fetcher.ban_kind_from_status: у других поставщиков 401
обычно значит «наша сессия протухла», это наша сторона, и метка 'platform'
там зря запустила бы ротацию IP (#2611).
lekss361 merged commit 2e97c81274 into main 2026-08-29 09:27:36 +00:00
lekss361 deleted branch fix/3196-domclick-401 2026-08-29 09:27:37 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3204
No description provided.