fix(scraper-kit/yandex): full-load on_bucket отдаёт список лотов бакета, а не int (#3375) #3378

Merged
bot-backend merged 2 commits from fix/3375-yandex-fullload-on-bucket-contract into main 2026-09-05 21:46:35 +00:00
Collaborator

Closes #3375.

Дефект. run_yandex_full_load._on_bucket(bucket_key, lots, complete) делает save_listings(db, lots), unique_fetched += len(lots), record_yandex_price_history(db, lots) — это ЕДИНСТВЕННЫЙ канал сохранения в yandex full-load (результат fetch_all_secondary отбрасывается). Провайдер yandex звал on_bucket(bucket_key, len(seen), not capped) — int вместо списка → TypeError: object of type 'int' has no len(), лоты не сохранялись.

Фикс. В providers/yandex/serp.py _leaf/_degraded копят bucket_lots в тех же ветках, где лот кладётся в общий seen (только новые → unique_fetched честен), и отдают список во все 3 вызова on_bucket — как у cian/avito (on_bucket(bucket_key, bucket_lots, complete)). Других int-вызывающих нет (grep "on_bucket(" — 6 вызовов: 3 yandex + cian/avito списки; у domclick своего нет). _mark_bucket/containment/scheduler не тронуты.

Тесты. Parity-фикстура _StubbedYandexScraper — настоящий fetch_all_secondary → _walk_price_range → _leaf, замокан только gate-JSON; test_yandex_full_load_saves_lot_list_from_real_provider проверяет isinstance(lots, list) + ScrapedLot в каждом save_listings и unique_fetched == call_count > 0. Переименован вводивший в заблуждение _count: int_lots в старых тестах.

Фальсификация (git apply -R хунка serp.py): TypeError: object of type 'int' has no len() — 1 failed. Восстановлено — зелено.

Прогоны: -k yandex 373 passed (rc=0); полный backend 5476 passed, 35 skipped (rc=0).

Приёмка на проде (открытая, до 2026-09-13): первый yandex full-load после деплоя — counters.unique_fetched > 0 и рост listings по source=yandex за окно прогона, без TypeError в логах.

Closes #3375. **Дефект.** `run_yandex_full_load._on_bucket(bucket_key, lots, complete)` делает `save_listings(db, lots)`, `unique_fetched += len(lots)`, `record_yandex_price_history(db, lots)` — это ЕДИНСТВЕННЫЙ канал сохранения в yandex full-load (результат `fetch_all_secondary` отбрасывается). Провайдер yandex звал `on_bucket(bucket_key, len(seen), not capped)` — int вместо списка → `TypeError: object of type 'int' has no len()`, лоты не сохранялись. **Фикс.** В `providers/yandex/serp.py` `_leaf`/`_degraded` копят `bucket_lots` в тех же ветках, где лот кладётся в общий `seen` (только новые → `unique_fetched` честен), и отдают список во все 3 вызова `on_bucket` — как у cian/avito (`on_bucket(bucket_key, bucket_lots, complete)`). Других int-вызывающих нет (`grep "on_bucket("` — 6 вызовов: 3 yandex + cian/avito списки; у domclick своего нет). `_mark_bucket`/containment/scheduler не тронуты. **Тесты.** Parity-фикстура `_StubbedYandexScraper` — настоящий `fetch_all_secondary → _walk_price_range → _leaf`, замокан только gate-JSON; `test_yandex_full_load_saves_lot_list_from_real_provider` проверяет `isinstance(lots, list)` + `ScrapedLot` в каждом `save_listings` и `unique_fetched == call_count > 0`. Переименован вводивший в заблуждение `_count: int` → `_lots` в старых тестах. **Фальсификация** (`git apply -R` хунка serp.py): `TypeError: object of type 'int' has no len()` — 1 failed. Восстановлено — зелено. **Прогоны:** `-k yandex` 373 passed (rc=0); полный backend `5476 passed, 35 skipped` (rc=0). **Приёмка на проде (открытая, до 2026-09-13):** первый yandex full-load после деплоя — `counters.unique_fetched > 0` и рост `listings` по source=yandex за окно прогона, без `TypeError` в логах.
bot-backend added 1 commit 2026-09-05 21:04:20 +00:00
fix(scraper-kit): yandex on_bucket отдаёт лоты бакета, а не len(seen)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
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 5m3s
e04e315203
`_leaf`/`_degraded` звали on_bucket(bucket_key, len(seen), complete) — int
уезжал в run_yandex_full_load._on_bucket и дальше в save_listings
(`for lot in lots`) → TypeError, ручной full-load Яндекса не сохранял ничего.
Контракт выровнен по cian/avito: провайдер копит лоты бакета (новые в seen)
и отдаёт список. Parity-фикстура подменяла скрапер целиком и слала list по
построению — добавлен прогон run_yandex_full_load через НАСТОЯЩИЙ
YandexRealtyScraper (замокан только gate-JSON транспорт).

Closes #3375
Light1YT added 1 commit 2026-09-05 21:38:21 +00:00
test(#3375): стаб доходит до _degraded и многостраничного листа; комментарий про красноту
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 10s
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 5m9s
235cc3065e
bot-backend merged commit ea4fb88b66 into main 2026-09-05 21:46:35 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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#3378
No description provided.