fix(tradein/cian): показать, ЧТО пришло вместо состояния ЖК-страницы, и честно закрывать нулевой прогон (#2767) #2768

Merged
bot-backend merged 1 commit from fix/2767-newbuilding-diagnose into main 2026-08-07 08:06:26 +00:00
Collaborator

Что не так

newbuilding_enrich восемь суток подряд: 25 попыток за прогон, ноль обогащённых записей, статус каждый раз done. Отказ на РАЗБОРЕ, не в сети — в полученной странице нет initialState.

Два объяснения, и по логу их было не различить: изменилась разметка ЖК-карточки ИЛИ пришла защитная заглушка. Ни размера ответа, ни признаков защиты в лог не писалось.

Что сделано

1. Видно, ЧТО пришло. _describe_parse_miss() в providers/cian/newbuilding.py дописывает к строке отказа html_len=<N> antibot_markers=<...>. Здоровая ЖК-карточка — 1.17 МБ с состоянием (verified live 2026-06-15), страница без состояния — подпись антибота (#972), поэтому одно число разделяет гипотезы:

  • ~1 МБ — страница целая, изменилась разметка (наша задача);
  • десятки КБ — защитная заглушка, антибот достаёт браузерный тракт (внешнее).

Функция называет найденное и НЕ называет причину — сообщение со знаком вопроса дальше читается как факт.

2. Честный статус. Финал прогона уходит в ОБЩИЙ runs.mark_backfill_finished (#2695), через который задача не проходила: её счётчики называются иначе, чем читает финализатор, поэтому любой прогон закрывался mark_done. to_backfill_counters() добавляет attempted/enriched/failed. attempted НЕ включает пропущенные уже-обогащённые дома — прогону, которому нечего делать, отказ не приписывается. Блоки источника задача не считает вовсе → нулевой прогон это failed (наш тракт), а не banned: вины площадки здесь не доказано (#2764).

3. Разбор не чинится — пока неизвестно, что приходит, правка разбора была бы угадыванием.

Test plan

  • tests/test_2767_newbuilding_parse_miss.py — 6 проверок; падают на коде до правки (проверено ревертом каждого файла по отдельности: без правки провайдера — ImportError на маркере, без правки задачи — 3 failed на mark_done вместо финализатора)
  • pytest -q (tradein backend, полный сьют) — 3960 passed
  • ruff check + ruff-format
  • Прод: следующий прогон 08.08 в 00:39 UTC. Сегодня эффект проверить НЕЛЬЗЯ — это «не проверено», а не «работает».

Критерий приёмки на завтра: в логе tradein-scraper у строк initialState extraction failed появился html_len=, и статус прогона newbuilding_enrich перестал быть done.

Refs #2767

## Что не так `newbuilding_enrich` восемь суток подряд: 25 попыток за прогон, **ноль** обогащённых записей, статус каждый раз `done`. Отказ на РАЗБОРЕ, не в сети — в полученной странице нет `initialState`. Два объяснения, и по логу их было не различить: изменилась разметка ЖК-карточки ИЛИ пришла защитная заглушка. Ни размера ответа, ни признаков защиты в лог не писалось. ## Что сделано **1. Видно, ЧТО пришло.** `_describe_parse_miss()` в `providers/cian/newbuilding.py` дописывает к строке отказа `html_len=<N> antibot_markers=<...>`. Здоровая ЖК-карточка — 1.17 МБ с состоянием (verified live 2026-06-15), страница без состояния — подпись антибота (#972), поэтому одно число разделяет гипотезы: - **~1 МБ** — страница целая, изменилась разметка (наша задача); - **десятки КБ** — защитная заглушка, антибот достаёт браузерный тракт (внешнее). Функция называет найденное и НЕ называет причину — сообщение со знаком вопроса дальше читается как факт. **2. Честный статус.** Финал прогона уходит в ОБЩИЙ `runs.mark_backfill_finished` (#2695), через который задача не проходила: её счётчики называются иначе, чем читает финализатор, поэтому любой прогон закрывался `mark_done`. `to_backfill_counters()` добавляет `attempted`/`enriched`/`failed`. `attempted` НЕ включает пропущенные уже-обогащённые дома — прогону, которому нечего делать, отказ не приписывается. Блоки источника задача не считает вовсе → нулевой прогон это `failed` (наш тракт), а не `banned`: вины площадки здесь не доказано (#2764). **3. Разбор не чинится** — пока неизвестно, что приходит, правка разбора была бы угадыванием. ## Test plan - [x] `tests/test_2767_newbuilding_parse_miss.py` — 6 проверок; падают на коде до правки (проверено ревертом каждого файла по отдельности: без правки провайдера — ImportError на маркере, без правки задачи — 3 failed на `mark_done` вместо финализатора) - [x] `pytest -q` (tradein backend, полный сьют) — 3960 passed - [x] ruff check + ruff-format - [ ] Прод: следующий прогон **08.08 в 00:39 UTC**. Сегодня эффект проверить НЕЛЬЗЯ — это «не проверено», а не «работает». **Критерий приёмки на завтра:** в логе `tradein-scraper` у строк `initialState extraction failed` появился `html_len=`, и статус прогона `newbuilding_enrich` перестал быть `done`. Refs #2767
bot-backend added 1 commit 2026-08-07 07:44:14 +00:00
fix(tradein/cian): показать, ЧТО пришло вместо состояния ЖК-страницы, и честно закрывать нулевой прогон (#2767)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 8s
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 / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 3m53s
575769e706
newbuilding_enrich восемь суток подряд делал 25 попыток, обогащал ноль записей
и каждый раз закрывался статусом 'done'. Отказ происходит на разборе:
initialState в полученной странице нет. Двух объяснений — изменилась разметка
или пришла защитная заглушка — по логу было не различить: ни размера ответа,
ни признаков защиты в нём не было.

Разделяет их одно число. Здоровая ЖК-карточка весит 1.17 МБ и содержит
состояние (verified live 2026-06-15), а страница без состояния — подпись
антибота (#972). Поэтому строка отказа теперь несёт html_len и перечисление
найденных маркеров защиты (_describe_parse_miss). Это диагностика, не диагноз:
функция называет найденное и не называет причину.

Разбор НЕ чинится: пока неизвестно, что приходит, любая правка разбора —
угадывание.

Статус прогона уходит в общий финализатор runs.mark_backfill_finished (#2695),
через который эта задача не проходила: счётчики задачи называются иначе, чем
читает финализатор, поэтому любой прогон закрывался mark_done.
to_backfill_counters() добавляет attempted/enriched/failed к своим счётчикам.
attempted не включает пропущенные уже-обогащённые дома — прогон, которому
нечего делать, отказом не является. Блоки источника задача не считает вовсе,
так что нулевой прогон помечается 'failed' (наш тракт), а не 'banned': вины
площадки здесь не доказано (#2764).

Refs #2767
bot-backend merged commit 5046ac7b4e into main 2026-08-07 08:06:26 +00:00
bot-backend deleted branch fix/2767-newbuilding-diagnose 2026-08-07 08:06:26 +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#2768
No description provided.