feat(tradein/avito): полный обход качает вторичку родным фильтром пути (#3033) #3039

Merged
bot-backend merged 1 commit from feat/3033-avito-native-secondary into main 2026-08-21 14:22:48 +00:00
Collaborator

Summary

  • fetch_all_secondary(secondary_only=True) строил URL общей выдачи (/kvartiry/prodam/<room-ASgB…>): 100 % страниц (46 573 объявления в ЕКБ), новостройки — в корзину после разбора. Теперь _build_rooms_url в secondary-режиме (флаг на инстансе на время вызова, сброс в finally) строит читаемый путь /{city}/kvartiry/prodam/{room_readable}/vtorichka — Авито канонизирует редиректом (проверено автором issue вживую: 2 551 vs 46 573). Query (s, p, pmin, pmax) без изменений — бисекция по цене работает как раньше, но по распределению вторички (побочно чинится калибровка брекетов).
  • Post-parse фильтр оставлен как страховка и счётчик: last_dropped_nbAvitoFullLoadCounters.dropped_novostroyki (зеркало cian #1781). При работающем пути ≈0; рост = площадка перестала уважать путь — видно по числу в scrape_runs.counters, а не по тишине.
  • Редиректы: browser-режим (camoufox) следует сам; curl_cffi — allow_redirects по умолчанию True (проверено в workspace-venv, явных переопределений в serp.py/_base.py нет).
  • Не трогал fetch_around (city-sweep по якорям) и fetch_by_rooms (вызовов нет): постановка про полный обход; city-sweep по геоточкам намеренно берёт оба сегмента.

Test plan

  • backend/tests/test_3033_avito_native_secondary_filter.py (workspace-venv, без сети: подмена _fetch_serp_html): probe-URL всех seed-брекетов = /ekaterinburg/kvartiry/prodam/1-komnatnye/vtorichka + s/p/pmin; secondary_only=False — прежний URL; режим не течёт за вызов; все 7 комнатностей → читаемый префикс без ASgB; счётчик в to_dict(). На origin/main 4/6 красных по значению, 2 контроля зелёные.
  • существующие test_serp_city_location_urls / test_avito_serp_city_slug / test_1781 / test_avito_newbuilding_sweep — 26 passed; ruff check зелёный (scraper-kit форматтером не трогал — он не в хуке и не нормализован).
  • Живая приёмка возможна только когда Авито пускает (сейчас SERP-баны 37–83 %, #2827/#3034): первый avito_full_load после деплоя — unique_fetched ≈ прежний, страниц впятеро меньше, dropped_novostroyki ≈ 0. Если dropped_novostroyki остаётся в сотнях — редирект ведёт на общую выдачу, откатывать.

Refs #3033

## Summary - `fetch_all_secondary(secondary_only=True)` строил URL **общей** выдачи (`/kvartiry/prodam/<room-ASgB…>`): 100 % страниц (46 573 объявления в ЕКБ), новостройки — в корзину после разбора. Теперь `_build_rooms_url` в secondary-режиме (флаг на инстансе на время вызова, сброс в `finally`) строит **читаемый путь** `/{city}/kvartiry/prodam/{room_readable}/vtorichka` — Авито канонизирует редиректом (проверено автором issue вживую: 2 551 vs 46 573). Query (`s`, `p`, `pmin`, `pmax`) без изменений — бисекция по цене работает как раньше, но по распределению вторички (побочно чинится калибровка брекетов). - Post-parse фильтр **оставлен** как страховка и счётчик: `last_dropped_nb` → `AvitoFullLoadCounters.dropped_novostroyki` (зеркало cian #1781). При работающем пути ≈0; рост = площадка перестала уважать путь — видно по числу в `scrape_runs.counters`, а не по тишине. - Редиректы: browser-режим (camoufox) следует сам; curl_cffi — `allow_redirects` по умолчанию `True` (проверено в workspace-venv, явных переопределений в serp.py/_base.py нет). - Не трогал `fetch_around` (city-sweep по якорям) и `fetch_by_rooms` (вызовов нет): постановка про полный обход; city-sweep по геоточкам намеренно берёт оба сегмента. ## Test plan - [x] `backend/tests/test_3033_avito_native_secondary_filter.py` (workspace-venv, без сети: подмена `_fetch_serp_html`): probe-URL всех seed-брекетов = `/ekaterinburg/kvartiry/prodam/1-komnatnye/vtorichka` + `s/p/pmin`; `secondary_only=False` — прежний URL; режим не течёт за вызов; все 7 комнатностей → читаемый префикс без `ASgB`; счётчик в `to_dict()`. **На origin/main 4/6 красных по значению**, 2 контроля зелёные. - [x] существующие `test_serp_city_location_urls / test_avito_serp_city_slug / test_1781 / test_avito_newbuilding_sweep` — 26 passed; `ruff check` зелёный (scraper-kit форматтером не трогал — он не в хуке и не нормализован). - [ ] **Живая приёмка возможна только когда Авито пускает** (сейчас SERP-баны 37–83 %, #2827/#3034): первый `avito_full_load` после деплоя — `unique_fetched` ≈ прежний, страниц впятеро меньше, `dropped_novostroyki ≈ 0`. Если `dropped_novostroyki` остаётся в сотнях — редирект ведёт на общую выдачу, откатывать. Refs #3033
bot-backend added 1 commit 2026-08-21 14:16:09 +00:00
feat(tradein/avito): полный обход качает вторичку родным фильтром пути (#3033)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / 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 / 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 4m25s
1b47cc5d7a
Почему: fetch_all_secondary(secondary_only=True) строил URL ОБЩЕЙ выдачи
(/kvartiry/prodam/<room-ASgB…>), скачивал 100 % (46 573 объявления в ЕКБ)
и выбрасывал новостройки после разбора — 79,4 % страниц и антибан-бюджета
впустую. У Авито есть родной фильтр: читаемый путь
/kvartiry/prodam/1-komnatnye/vtorichka (редирект на канонический, 2 551
объявление) — проверено вживую 21.08.2026 (#3033). Чем полнее обход, тем
выше отказ (full_load 83 % banned/failed против newbuilding_sweep 9,5 %) —
объём сам по себе фактор бана.

Что: _build_rooms_url в secondary-режиме (флаг на инстансе на время
fetch_all_secondary, сбрасывается в finally) строит путь из читаемого
префикса room-slug + /vtorichka; query (s, p, pmin, pmax) без изменений —
ценовая бисекция работает как раньше, но уже по распределению вторички.
Post-parse фильтр остаётся страховкой и счётчиком: last_dropped_nb →
AvitoFullLoadCounters.dropped_novostroyki (зеркало cian #1781) — при
работающем пути ≈0, рост = Авито перестал уважать путь, видно по числу.

Тест: подмена _fetch_serp_html, probe-URL всех seed-брекетов; на main
красный по значению (ASgB-slug в пути, /vtorichka нет); контроли —
secondary_only=False не меняется, режим не течёт за пределы вызова.

Refs #3033
bot-backend merged commit 7382ae123d into main 2026-08-21 14:22:48 +00:00
bot-backend deleted branch feat/3033-avito-native-secondary 2026-08-21 14:22:49 +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#3039
No description provided.