fix(tradein/yandex): в очередь обогащения не берём то, что парсер отвергает до сети (#2674) #2738

Merged
bot-backend merged 1 commit from fix/detail-backfill-zero into main 2026-08-06 15:22:22 +00:00
Collaborator

Что было

yandex_detail_backfill, прогон 3300 (сегодня 11:05 UTC): attempted=5, failed=5, enriched=0, 23 секунды. Так закончились 32 прогона из 53, и сообщение винило капчу: «5 consecutive parse-None results (captcha wall?)».

Что на самом деле

Капчи нет. YandexDetailScraper.parse (providers/yandex/detail.py:150) первым делом ищет в URL /offer/<цифры>/ и без него возвращает None, не заглянув в HTML.

Замер прода 2026-08-06:

очередь (detail_enriched_at IS NULL) строк
realty.yandex.ru/offer/<id>/ 11 976
сайт застройщика (macroserver.ru, prospect-federation.ru, strana.com, …) 3 535
из них обогащено за всю историю 0
из 1 210 обогащённых имеют не-Яндексовый URL 0

Вред не в бесполезности, а в кучности: такие строки приходят пачками (один свип — один застройщик), поэтому «5 parse-None подряд» набиралось на первых позициях и обрывало весь прогон вместе с 12 тысячами разбираемых объявлений за ними. Верх очереди на момент прогона 3300 — ровно пять таких строк подряд (macroserver ×2, prospect-federation ×3), 4 паузы по 5 с + 5 быстрых запросов = те самые 23 секунды.

Яндекс НЕ сломан: 21 прогон из 53 обогащал, 1 409 успехов на 1 783 попытки, последний — 4 августа.

Что сделано

  • снапшот-SELECT гейтит по тому же признаку, по которому судит парсер (source_url ~ '/offer/[0-9]+');
  • отброшенное считается и едет в counters.unenrichable_pending — чтобы «обогащено 12k из 15.5k» не стало следующим немым нулём;
  • тест сверяет гейт очереди и гейт парсера на реальных прод-URL: расхождение = регрессия (падает на старом коде).

Test plan

  • pytest tests/tasks/test_yandex_detail_backfill.py — 13 passed; новый тест на старом коде падает на assert "source_url ~ CAST(:offer_url_pattern AS text)"
  • полный pytest бэкенда — 3854 passed
  • прод: окно 11:05 UTC (app/tasks/** входит в scraper-фильтр деплоя → контейнер пересоздаётся)

Refs #2674

## Что было `yandex_detail_backfill`, прогон 3300 (сегодня 11:05 UTC): `attempted=5, failed=5, enriched=0`, 23 секунды. Так закончились **32 прогона из 53**, и сообщение винило капчу: «5 consecutive parse-None results (captcha wall?)». ## Что на самом деле Капчи нет. `YandexDetailScraper.parse` (providers/yandex/detail.py:150) первым делом ищет в URL `/offer/<цифры>/` и без него возвращает `None`, **не заглянув в HTML**. Замер прода 2026-08-06: | очередь (detail_enriched_at IS NULL) | строк | |---|---| | `realty.yandex.ru/offer/<id>/` | 11 976 | | сайт застройщика (macroserver.ru, prospect-federation.ru, strana.com, …) | **3 535** | | из них обогащено за всю историю | **0** | | из 1 210 обогащённых имеют не-Яндексовый URL | **0** | Вред не в бесполезности, а в кучности: такие строки приходят пачками (один свип — один застройщик), поэтому «5 parse-None подряд» набиралось на первых позициях и обрывало **весь** прогон вместе с 12 тысячами разбираемых объявлений за ними. Верх очереди на момент прогона 3300 — ровно пять таких строк подряд (macroserver ×2, prospect-federation ×3), 4 паузы по 5 с + 5 быстрых запросов = те самые 23 секунды. Яндекс НЕ сломан: 21 прогон из 53 обогащал, 1 409 успехов на 1 783 попытки, последний — 4 августа. ## Что сделано - снапшот-SELECT гейтит по тому же признаку, по которому судит парсер (`source_url ~ '/offer/[0-9]+'`); - отброшенное считается и едет в `counters.unenrichable_pending` — чтобы «обогащено 12k из 15.5k» не стало следующим немым нулём; - тест сверяет гейт очереди и гейт парсера на реальных прод-URL: расхождение = регрессия (падает на старом коде). ## Test plan - [x] `pytest tests/tasks/test_yandex_detail_backfill.py` — 13 passed; новый тест на старом коде падает на `assert "source_url ~ CAST(:offer_url_pattern AS text)"` - [x] полный `pytest` бэкенда — 3854 passed - [ ] прод: окно 11:05 UTC (`app/tasks/**` входит в scraper-фильтр деплоя → контейнер пересоздаётся) Refs #2674
bot-backend added 1 commit 2026-08-06 15:17:21 +00:00
fix(tradein/yandex): в очередь обогащения не берём то, что парсер отвергает до сети (#2674)
All checks were successful
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 7s
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 / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 3m9s
fe9abff529
Прогон yandex_detail_backfill 3300 (11:05 UTC): 5 попыток, 5 отказов, ноль
обогащений, 23 секунды. Так закончились 32 прогона из 53 — и сообщение о них
винило капчу («5 consecutive parse-None results (captcha wall?)»).

Капчи там нет. `YandexDetailScraper.parse` первым делом ищет в URL
`/offer/<цифры>/` и без него возвращает None, ещё не заглянув в HTML. В очереди
3535 объявлений из 15511 — карточки новостроек, у которых source_url ведёт на
сайт застройщика (macroserver.ru, prospect-federation.ru, strana.com). Обогащено
из них за всю историю ноль; все 1210 обогащённых — вида realty.yandex.ru/offer/.

Вред не в бесполезности: такие строки идут пачками (один свип — один
застройщик), поэтому «5 parse-None подряд» набиралось на первых же позициях и
обрывало ВЕСЬ прогон вместе с 12 тысячами разбираемых объявлений за ними. Верх
очереди на момент прогона 3300 — ровно пять таких строк подряд.

Снапшот-SELECT теперь гейтит по тому же признаку, по которому судит парсер, а
размер отброшенного едет в counters.unenrichable_pending — чтобы «обогащено 12k
из 15.5k» не стало следующим немым нулём.

Тест сверяет оба гейта на реальных прод-URL: расхождение = регрессия.
bot-backend merged commit 4aec49f7fb into main 2026-08-06 15:22:22 +00:00
bot-backend deleted branch fix/detail-backfill-zero 2026-08-06 15:22:22 +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#2738
No description provided.