fix(tradein/domclick): рекан скрейпера на BFF JSON API + честный статус (#1846, #1968) #1979

Merged
lekss361 merged 2 commits from fix/tradein-domclick-bff-rewrite into main 2026-06-27 10:59:48 +00:00
Owner

Что и зачем

Старый DomClick-скрейпер (source='domklik') мёртв: /search?city_id=4&p=N снят в редизайне сайта, а VPS-IP забанен QRATOR'ом → прод domclick_city_sweep каждый запуск рапортовал done/0 листингов (0 в БД). Реанимация через живой JSON API, верифицированный живьём (playwright + прод docker exec tradein-scraper тест: 20 офферов, blocked=NO).

Закрывает развилку #1846 (реанимировать) vs #1968 (выпил из UI) — в пользу реанимации.

Контракт (верифицирован 2026-06-27)

  • LIST GET bff-search-web.domclick.ru/api/offers/v1 + COUNT /count/v1 через BrowserFetcher(source="domclick")generic provider → shared mobile proxy → обходит QRATOR (нового аккаунта/правок browser-pool НЕ нужно).
  • Гео ЕКБ: address=<region GUID> + aids=20561 (0 подмеса чужих городов, в отличие от avito-radius).
  • 6 room-бакетов st/1/2/3/4/5+; рекурсивный binary price-split для бакетов > offset-cap 2000 (rooms=2 ~2215 — единственный); count/v1 сайзит бакеты.
  • Поля → ScrapedLot: lat/lon ~100% (закрывает avito 54% NULL-lat), area/rooms/floor/total_floors/year_built/price/ЖК; per-card EKB geo-guard.

Честный статус (#1968)

  • QRATOR-блок или fetch-ошибки при 0 листингов → mark_failed, не mark_done.
  • Parse-ошибки per-page resilient (break бакета, partial lots сохраняются) — транзиентная битая страница не валит весь sweep.

Безопасность выката

  • Расписание DORMANT (enabled=false, pages=100) через 138_domclick_bff_rewrite_schedule.sql (idempotent UPDATE). Оператор включает после прод-smoke.
  • scrape_pipeline.py (shared) — хирургические правки только в run_domclick_city_sweep + counters; full pytest прогнан.

Качество

  • Adversarial review (6 lens × verify): найдено и исправлено 1 high (parse-failure abort масковал done/0) + 3 medium + 3 low.
  • 42 scraper-теста (price-split boundaries, parse-error resilience, honest-status), полный backend suite зелёный, ruff чист.
  • Layer B (detail: renovation/wallType/priceHistory/AVM) — отдельный follow-up к #1846.

После merge

Прод-smoke вручную: ручной DORMANT-триггер (UPDATE scrape_schedules SET next_run_at=now() или одноразовый прогон в tradein-scraper) → проверка появления domklik-листингов + честного статуса, затем enabled=true.

## Что и зачем Старый DomClick-скрейпер (`source='domklik'`) **мёртв**: `/search?city_id=4&p=N` снят в редизайне сайта, а VPS-IP забанен QRATOR'ом → прод `domclick_city_sweep` каждый запуск рапортовал `done`/0 листингов (0 в БД). Реанимация через **живой JSON API**, верифицированный живьём (playwright + прод `docker exec tradein-scraper` тест: 20 офферов, `blocked=NO`). Закрывает развилку **#1846** (реанимировать) vs **#1968** (выпил из UI) — в пользу реанимации. ## Контракт (верифицирован 2026-06-27) - **LIST** `GET bff-search-web.domclick.ru/api/offers/v1` + **COUNT** `/count/v1` через `BrowserFetcher(source="domclick")` → `generic` provider → **shared mobile proxy** → обходит QRATOR (нового аккаунта/правок browser-pool НЕ нужно). - Гео ЕКБ: `address=<region GUID>` + `aids=20561` (0 подмеса чужих городов, в отличие от avito-radius). - 6 room-бакетов `st/1/2/3/4/5+`; рекурсивный binary **price-split** для бакетов > offset-cap 2000 (rooms=2 ~2215 — единственный); `count/v1` сайзит бакеты. - Поля → `ScrapedLot`: **lat/lon ~100%** (закрывает avito 54% NULL-lat), area/rooms/floor/total_floors/year_built/price/ЖК; per-card EKB geo-guard. ## Честный статус (#1968) - QRATOR-блок **или** fetch-ошибки при 0 листингов → `mark_failed`, не `mark_done`. - Parse-ошибки **per-page resilient** (break бакета, partial lots сохраняются) — транзиентная битая страница не валит весь sweep. ## Безопасность выката - Расписание **DORMANT** (`enabled=false`, `pages=100`) через `138_domclick_bff_rewrite_schedule.sql` (idempotent UPDATE). Оператор включает после прод-smoke. - `scrape_pipeline.py` (shared) — хирургические правки только в `run_domclick_city_sweep` + counters; full pytest прогнан. ## Качество - **Adversarial review** (6 lens × verify): найдено и исправлено 1 high (parse-failure abort масковал done/0) + 3 medium + 3 low. - **42** scraper-теста (price-split boundaries, parse-error resilience, honest-status), полный backend suite зелёный, ruff чист. - Layer B (detail: renovation/wallType/priceHistory/AVM) — отдельный follow-up к #1846. ## После merge Прод-smoke вручную: ручной DORMANT-триггер (`UPDATE scrape_schedules SET next_run_at=now()` или одноразовый прогон в `tradein-scraper`) → проверка появления `domklik`-листингов + честного статуса, затем `enabled=true`.
lekss361 added 2 commits 2026-06-27 10:58:10 +00:00
Old HTML scraper dead: /search?city_id retired in DomClick redesign + VPS IP
QRATOR-banned (prod domclick_city_sweep reported done/0 every run). New path:

- GET bff-search-web.domclick.ru/api/offers/v1 + count/v1 via
  BrowserFetcher(source="domclick") -> generic provider -> shared mobile proxy
  -> bypasses QRATOR (prod-verified live: 20 items returned, no block).
- Sweeps 6 room buckets (st/1/2/3/4/5+); recursive binary price-split for
  oversized buckets (rooms=2 ~2215 > offset cap 2000); count/v1 sizes buckets.
- Maps SERP JSON -> ScrapedLot with lat/lon at ~100% (closes avito 54% NULL-lat
  gap); per-card EKB geo-guard.
- Honest status (#1968): QRATOR block OR fetch errors with 0 lots -> mark_failed,
  not mark_done. Parse failures are per-page resilient (break bucket, keep partial
  lots) so a transient bad page never aborts the whole sweep.
- Schedule shipped DORMANT (enabled=false, pages=100) via
  138_domclick_bff_rewrite_schedule.sql; operator enables after prod smoke.

42 scraper tests (price-split boundaries, parse-error resilience, honest status);
full backend suite green; ruff clean. Layer B (detail renovation/wallType/
priceHistory) deferred to #1846 follow-up.
Merge remote-tracking branch 'forgejo/main' into fix/tradein-domclick-bff-rewrite
All checks were successful
CI / changes (pull_request) Successful in 11s
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
4a63b8f7d7
lekss361 merged commit 684385263e into main 2026-06-27 10:59:48 +00:00
lekss361 deleted branch fix/tradein-domclick-bff-rewrite 2026-06-27 10:59:48 +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#1979
No description provided.