fix(tradein/avito): страница SERP отдаёт 60 карточек, а не 50 — лишние 17% запросов #3041
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3041
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/avito-offers-per-page"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Хвост от #3033, не вошедший в #3039. Одна константа плюс регрессионный тест.
Замер
Живьём 2026-08-21 через
tradein-browser(camoufox, JS исполняется — не curl_cffi, который на этом пути отдаёт app-shell без карточек): 59-60 уникальныхdata-item-idна странице выдачи.«Лишние» сверх 50 — это не рекламный блок и не секция «похожие». Это обычные объявления с платным продвижением (
vas-icon_type-promoted), они лежат в том же списке подpage-title/countи собираются наравне с остальными.Направление эффекта — обратное тому, как это легко прочитать
Константа участвует только в
ceil(total / PAGE). Значит занижение размера страницы завышало расчётное число страниц:pages_neededдля 1000 объявленийПоследствия занижения:
tail_lossсчитался какtotal − cap × 50и завышал потерю в предупреждениях;completeв пагинации листа (pages_needed <= max_pages) чаще ложно показывал «неполно», из-за чего бакет реже помечался завершённым.Тихой потери данных не было. Я специально искал условие вида «страница вернула меньше PAGE карточек, значит последняя» — такого в коде нет, пагинация ограничена только
max_pages. Правка ценна тем, что убирает лишние запросы и чинит враньё в метриках, а не тем, что спасает данные.Это стоит подчеркнуть, потому что в исходном разборе направление было сформулировано наоборот («занижала pages_needed → тихий tail-loss»). Тест
test_pages_needed_arithmetic_uses_the_constantзакрепляет верную трактовку, чтобы она не потерялась.Тесты
tradein-mvp/backend/tests/test_avito_offers_per_page.py— 4 проверки:ceilпри 60 даёт меньше страниц, чем при 50 (направление эффекта);Прогнано: новый файл 4 passed;
pytest -k avito— 249 passed, 1 skipped;ruff checkчисто.Отдельно: ложная тревога, которую проверил и не подтвердил
При этой же работе прозвучало, что города
kamensk_uralskiyиverkhnyaya_pyshmaякобы 404-ят из-за расхождения слагов (у Авитоkamensk-uralskiyчерез дефис иverhnyaya_pyshmaбез «к»). Не подтвердилось:orchestration/pipeline.py:413,CityLocation("kamensk-uralskiy", …), и рядом дважды стоит комментарий ровно про эту особенность.Проверка шла в обход маппинга, поэтому и дала 404. Issue не заводил.
Refs #3033
Замер живьём 2026-08-21 через tradein-browser (camoufox, JS исполняется): 59-60 уникальных `data-item-id` на странице выдачи. «Лишние» сверх 50 — обычные объявления с платным продвижением (`vas-icon_type-promoted`), они лежат в том же списке под `page-title/count`, а не отдельным рекламным блоком, и собираются наравне с остальными. Направление эффекта важно понимать правильно. Константа участвует ТОЛЬКО в `ceil(total / PAGE)`, поэтому занижение размера страницы ЗАВЫШАЛО расчётное число страниц, а не занижало: - запрашивали примерно на 17 % страниц больше, чем нужно; при доле банов 37-83 % по avito-заданиям лишние запросы — основная цена ошибки; - `tail_loss` считался как `total - cap * 50` и завышал потерю; - флаг `complete` в пагинации листа чаще ложно показывал «неполно». Тихой потери данных НЕ было: условия «страница вернула меньше PAGE карточек, значит последняя» в коде нет, пагинация ограничена только `max_pages`. Тест закрепляет и значение, и направление арифметики, чтобы неверная трактовка не вернулась при следующем рефакторинге. Найдено при разборе Авито сверкой живого браузера со скраппером; полный разбор — в волте `research/Avito_Live_Browser_Recon_0821.md`. Refs #3033