fix(tradein/domclick): распознанный QRATOR-блок свипа — ban_kind='platform', не 'unknown' (#2687) #2832

Merged
bot-backend merged 1 commit from fix/2687-domclick-ban-kind-platform into main 2026-08-12 20:55:05 +00:00
Collaborator

Что чинит (часть разбора #2687 / #2657)

Ветка if counters.blocked: в run_domclick_city_sweep входится только когда скрейпер поднял DomClickBlockedError (площадка отдала QRATOR block-страницу, counters.blocked==1). Это ровно определение BAN_KIND_PLATFORM («площадка нас заблокировала»). Свип звал mark_banned без ban_kind → дефолт 'unknown' (#2764), хотя диагноз здесь установлен, а не «не установлен».

Прод 2026-08-12:

run source status blocked ban_kind
3751 domclick_city_sweep banned 1 unknown
3675 domclick_city_sweep banned 1 unknown
3594 domclick_city_sweep banned 1 unknown

Мониторинг #2657 разводит «тракт/прокси» (infra) и «площадка» (platform) именно по ban_kind. Под 'unknown' это различение слепо — тогда как здесь площадка себя показала (QRATOR), и это platform, симметрично тому, как AvitoBlockedErrorplatform в ban_kind_of_exception.

Тест

test_2687_domclick_ban_kind.py — свип с blocked=True уходит в mark_banned с ban_kind='platform'. Red на старом коде: без правки ban_kind не передаётся → None != 'platform'. Не удалось прогнать локально (нет venv с деп-деревом app/scraper_kit; прод read-only) — гейт прогонит CI; харнесс — клон рабочего _drive из test_2670.

Чего PR НЕ трогает

Вопрос #2687 про полный обход Авито — это разбор, не правка: полный обход ходит через пул (не мимо), а 0-seen у него — платформенный SERP-firewall (#2827), а не дефект проводки. Детали и опровергнутые предпосылки — в комментарии к #2687.

Связано: #2687, #2657, #2764, #2686.

## Что чинит (часть разбора #2687 / #2657) Ветка `if counters.blocked:` в `run_domclick_city_sweep` входится **только** когда скрейпер поднял `DomClickBlockedError` (площадка отдала QRATOR block-страницу, `counters.blocked==1`). Это ровно определение `BAN_KIND_PLATFORM` («площадка нас заблокировала»). Свип звал `mark_banned` **без** `ban_kind` → дефолт `'unknown'` (#2764), хотя диагноз здесь **установлен**, а не «не установлен». Прод 2026-08-12: | run | source | status | blocked | ban_kind | |---|---|---|---|---| | 3751 | domclick_city_sweep | banned | 1 | **unknown** | | 3675 | domclick_city_sweep | banned | 1 | **unknown** | | 3594 | domclick_city_sweep | banned | 1 | **unknown** | Мониторинг #2657 разводит «тракт/прокси» (`infra`) и «площадка» (`platform`) именно по `ban_kind`. Под `'unknown'` это различение слепо — тогда как здесь площадка **себя показала** (QRATOR), и это `platform`, симметрично тому, как `AvitoBlockedError` → `platform` в `ban_kind_of_exception`. ## Тест `test_2687_domclick_ban_kind.py` — свип с `blocked=True` уходит в `mark_banned` с `ban_kind='platform'`. **Red на старом коде**: без правки `ban_kind` не передаётся → `None != 'platform'`. Не удалось прогнать локально (нет venv с деп-деревом app/scraper_kit; прод read-only) — гейт прогонит CI; харнесс — клон рабочего `_drive` из `test_2670`. ## Чего PR НЕ трогает Вопрос #2687 про полный обход Авито — это **разбор, не правка**: полный обход ходит **через пул** (не мимо), а 0-seen у него — платформенный SERP-firewall (#2827), а не дефект проводки. Детали и опровергнутые предпосылки — в комментарии к #2687. Связано: #2687, #2657, #2764, #2686.
bot-backend added 1 commit 2026-08-12 10:38:08 +00:00
fix(tradein/domclick): распознанный QRATOR-блок свипа — ban_kind='platform', не 'unknown' (#2687)
All checks were successful
CI / changes (pull_request) Successful in 9s
CI Trade-In / changes (pull_request) Successful in 9s
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 3m59s
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
8bdae6224f
Ветка `if counters.blocked:` в run_domclick_city_sweep входится ТОЛЬКО когда
скрейпер поднял DomClickBlockedError (площадка отдала QRATOR block-страницу) —
это ровно определение BAN_KIND_PLATFORM. Свип звал mark_banned без ban_kind, и
все его баны падали в дефолт 'unknown' (#2764), хотя диагноз здесь УСТАНОВЛЕН
(блок распознан, gate по counters.blocked==1), а не «не установлен».

Прод 2026-08-12: domclick_city_sweep 3751/3675/3594 — все banned, blocked=1,
ban_kind='unknown'. Мониторинг #2657 разводит тракт/прокси (infra) и площадку
(platform) по ban_kind — под 'unknown' это различение слепо.

Тест red-on-old: свип с blocked=True уходит в mark_banned без ban_kind → None.
bot-backend merged commit 4b527751b9 into main 2026-08-12 20:55:05 +00:00
Author
Collaborator

Проверено перед мержем — числа актуальны и даже занижены

На проде за 14 суток ban_kind='unknown' у десяти прогонов Домклика, а не у трёх:

источник ban_kind прогонов последний
domclick_detail_backfill unknown 7 12.08 17:39
domclick_city_sweep unknown 3 12.08 04:28
avito_detail_backfill platform 4 10.08 01:17

Контраст с Авито показателен: там механизм работает и диагноз доезжает. То есть это не «нигде не сделано», а «сделано для одного источника из двух».

Остаток, который этот PR не покрывает — 7 из 10

Правка входит в ветку if counters.blocked: внутри run_domclick_city_sweep — это 3 бана. Оставшиеся 7 приходят от domclick_detail_backfill, и путь у него другой: сама задача mark_banned не зовёт, она считает consecutive_blocks и обрывается по порогу. Отображение ban_kind_of_exception перечисляет только исключения Авито (AvitoSidecarUnavailableError, NoProxyAvailableError, AvitoBlockedError), DomClickBlockedError в нём отсутствует, и всё прочее уходит в unknown.

Не блокирую этим мерж: PR заявляет свип и делает ровно свип, с красным прогоном. Расширять область правки задним числом — плохой размен.

Но остаток стоит взять следом, и он больше исходного: 7 банов против 3, причём именно у обогащения, где блок распознан генуинноparse_detail_html ловит маркеры QRATOR при HTTP 200 и зовёт report_ban (providers/domclick/detail.py:553). Диагноз там установлен ровно так же, как в свипе, и так же не доезжает до scrape_runs.

Что важнее классификации

Пока сбор Домклика мёртв целиком, и ban_kind этого не чинит — только делает различимым:

domclick_city_sweep        7 прогонов за 7 суток, успешных 0, забанено 3
domclick_detail_backfill   7 прогонов за 7 суток, успешных 0, забанено 7

Последний полноценный обход — 18.07, 5937 объявлений за сутки. Дальше ручеёк: 307 (31.07), 313 (10.08), 59 (12.08). Второго августа деактиватор снял 6131 объявление разом — не потому, что они исчезли с площадки, а потому что мы перестали их видеть и сработал порог свежести.

Сегодня активными числятся 752 из 6779 (11.1%). Это и есть настоящий размер задачи; классификация бана — первый шаг к тому, чтобы отказ было видно, а не последний.

## Проверено перед мержем — числа актуальны и даже занижены На проде за 14 суток `ban_kind='unknown'` у **десяти** прогонов Домклика, а не у трёх: | источник | ban_kind | прогонов | последний | |---|---|---:|---| | `domclick_detail_backfill` | **unknown** | 7 | 12.08 17:39 | | `domclick_city_sweep` | **unknown** | 3 | 12.08 04:28 | | `avito_detail_backfill` | platform | 4 | 10.08 01:17 | Контраст с Авито показателен: там механизм работает и диагноз доезжает. То есть это не «нигде не сделано», а «сделано для одного источника из двух». ## Остаток, который этот PR не покрывает — 7 из 10 Правка входит в ветку `if counters.blocked:` внутри `run_domclick_city_sweep` — это 3 бана. Оставшиеся **7** приходят от `domclick_detail_backfill`, и путь у него другой: сама задача `mark_banned` не зовёт, она считает `consecutive_blocks` и обрывается по порогу. Отображение `ban_kind_of_exception` перечисляет только исключения Авито (`AvitoSidecarUnavailableError`, `NoProxyAvailableError`, `AvitoBlockedError`), `DomClickBlockedError` в нём отсутствует, и всё прочее уходит в `unknown`. **Не блокирую этим мерж:** PR заявляет свип и делает ровно свип, с красным прогоном. Расширять область правки задним числом — плохой размен. Но остаток стоит взять следом, и он больше исходного: 7 банов против 3, причём именно у обогащения, где блок распознан **генуинно** — `parse_detail_html` ловит маркеры QRATOR при HTTP 200 и зовёт `report_ban` (`providers/domclick/detail.py:553`). Диагноз там установлен ровно так же, как в свипе, и так же не доезжает до `scrape_runs`. ## Что важнее классификации Пока сбор Домклика мёртв целиком, и `ban_kind` этого не чинит — только делает различимым: ``` domclick_city_sweep 7 прогонов за 7 суток, успешных 0, забанено 3 domclick_detail_backfill 7 прогонов за 7 суток, успешных 0, забанено 7 ``` Последний полноценный обход — **18.07**, 5937 объявлений за сутки. Дальше ручеёк: 307 (31.07), 313 (10.08), 59 (12.08). Второго августа деактиватор снял **6131 объявление разом** — не потому, что они исчезли с площадки, а потому что мы перестали их видеть и сработал порог свежести. Сегодня активными числятся **752 из 6779** (11.1%). Это и есть настоящий размер задачи; классификация бана — первый шаг к тому, чтобы отказ было видно, а не последний.
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#2832
No description provided.