Yandex detail-enrichment не реализован: нет save + detail не fetch'ится в свипе (area_m2 23%, repair 1%) #1553

Closed
opened 2026-06-16 10:48:45 +00:00 by lekss361 · 1 comment
Owner

Находка (field-audit cian/yandex, verified прод 2026-06-16)

Реальное заполнение ключевых полей (listings):

source total rooms area_m2 floor living kitchen repair addr
cian 19124 100% 99.9% 100% 72% 0% 31% 100%
yandex 3952 97% 23% 99% 0% 0% 1% 97%

(базовые rooms/area/floor/addr пишутся на этапе search-save; detail-only поля — нет.)

Yandex — главная дыра (🔴)

YandexDetailScraper (yandex_detail.py) парсит 17 полей (rooms, area_m2, floor, address, repair, views, agency, metro, photos, newbuilding...), но:

  1. Нет save_detail_enrichment — admin endpoint scrape_yandex_detail (admin.py:1427) read-only, ничего не пишет.
  2. Detail не вызывается в свипеYandexDetailScraper используется ТОЛЬКО из ad-hoc admin endpoint; в yandex_city_sweep/pipeline нет detail-стадии (в отличие от avito ENRICH_DETAIL / cian DETAIL).
  3. conflict_resolution.py:106-112 ссылается на yandex_detail как источник agency_*/views_total_yandex/publish_date_relative — но эти поля мёртвые (detail не fetch'ится → не сохраняется).

→ Следствие: yandex area_m2 23% (только из SERP, где площадь не всегда есть), repair 1%, living/kitchen 0.

Нужно: (а) реализовать save_detail_enrichment(db, listing_id, enrichment) в yandex_detail.py (паттерн cian_detail.py:242); (б) интегрировать detail-стадию в yandex sweep (аналог avito ENRICH_DETAIL scrape_pipeline.py), через yandex-прокси (YANDEX_PROXY_URL); (в) проверить наличие колонок (agency_*, views_total_yandex есть по миграции 033). Scope средний-большой.

Cian — minor (🟡)

cian базово полон. Единственная дыра: kitchen_area_m2 = 0cian_detail.py извлекает ~9 полей из raw_offer, не берёт kitchen area (хотя в JSON оно обычно есть). living_area_m2 уже 72%. Можно добавить kitchen-extraction точечно (cian_detail.py:111 raw_offer).

Контекст

  • avito detail-парсер — эталон (поля захватываются полностью после PR #1550).
  • Аудит провёл статически + verify на проде (статика преувеличивала «потери» cian — search-save их пишет).
  • Не входит в активный coverage-фикс (#1549/#1550/#1552 — те про geom + avito). Это про yandex/cian полноту полей.
## Находка (field-audit cian/yandex, verified прод 2026-06-16) Реальное заполнение ключевых полей (`listings`): | source | total | rooms | area_m2 | floor | living | kitchen | repair | addr | |---|---|---|---|---|---|---|---|---| | **cian** | 19124 | 100% | 99.9% | 100% | 72% | **0%** | 31% | 100% | | **yandex** | 3952 | 97% | **23%** | 99% | **0%** | **0%** | **1%** | 97% | (базовые rooms/area/floor/addr пишутся на этапе search-save; detail-only поля — нет.) ## Yandex — главная дыра (🔴) `YandexDetailScraper` (`yandex_detail.py`) **парсит 17 полей** (rooms, area_m2, floor, address, repair, views, agency, metro, photos, newbuilding...), но: 1. **Нет `save_detail_enrichment`** — admin endpoint `scrape_yandex_detail` (`admin.py:1427`) read-only, ничего не пишет. 2. **Detail не вызывается в свипе** — `YandexDetailScraper` используется ТОЛЬКО из ad-hoc admin endpoint; в `yandex_city_sweep`/pipeline нет detail-стадии (в отличие от avito ENRICH_DETAIL / cian DETAIL). 3. `conflict_resolution.py:106-112` ссылается на `yandex_detail` как источник `agency_*`/`views_total_yandex`/`publish_date_relative` — но эти поля **мёртвые** (detail не fetch'ится → не сохраняется). → Следствие: yandex area_m2 23% (только из SERP, где площадь не всегда есть), repair 1%, living/kitchen 0. **Нужно:** (а) реализовать `save_detail_enrichment(db, listing_id, enrichment)` в yandex_detail.py (паттерн cian_detail.py:242); (б) интегрировать detail-стадию в yandex sweep (аналог avito ENRICH_DETAIL `scrape_pipeline.py`), через yandex-прокси (`YANDEX_PROXY_URL`); (в) проверить наличие колонок (`agency_*`, `views_total_yandex` есть по миграции 033). Scope средний-большой. ## Cian — minor (🟡) cian базово полон. Единственная дыра: `kitchen_area_m2 = 0` — `cian_detail.py` извлекает ~9 полей из raw_offer, не берёт kitchen area (хотя в JSON оно обычно есть). `living_area_m2` уже 72%. Можно добавить kitchen-extraction точечно (`cian_detail.py:111` raw_offer). ## Контекст - avito detail-парсер — эталон (поля захватываются полностью после PR #1550). - Аудит провёл статически + verify на проде (статика преувеличивала «потери» cian — search-save их пишет). - Не входит в активный coverage-фикс (#1549/#1550/#1552 — те про geom + avito). Это про yandex/cian полноту полей.
lekss361 added the
enhancement
scope/backend
scrapers
labels 2026-06-16 10:48:52 +00:00
Author
Owner

Уточнение по реализации (снижает scope)

Yandex-свип уже fetch'ит detail-страницу — Phase 3 address-enrich в run_yandex_city_sweep (scrape_pipeline.py:819-823) запрашивает detail ради извлечения полного адреса из <title> (через yandex_address_backfill._fetch_and_update_one, прокси scraper_proxy_url). Т.е. fetch-инфра + прокси уже на месте — не строить с нуля.

Минимальный путь:

  1. save_detail_enrichment(db, listing_id, enrichment) в yandex_detail.py (паттерн cian_detail.py:242; колонки rooms/area_m2/floor/repair_state/views/agency_*/metro_stations — проверить миграцию 033).
  2. В Phase 3 свипа — вместо лёгкого title-only fetch вызвать YandexDetailScraper.fetch_detail(offer_url) (полный DetailEnrichment, 17 полей) → save_detail_enrichment. Адрес из detail уже включён, так что address-enrich покрывается тем же запросом (1 fetch вместо 2).
  3. Для backlog 3952 существующих — отдельный yandex_detail_backfill (точный аналог avito_detail_backfill #1552: snapshot по area_m2 IS NULL / detail-полям, прокси YANDEX_PROXY_URL, budget, scheduler-source + миграция).

NB: yandex_city_sweep сейчас enabled=false (DORMANT, #561) — backfill-task (п.3) даст обогащение независимо от dormant-свипа.

## Уточнение по реализации (снижает scope) Yandex-свип **уже fetch'ит detail-страницу** — Phase 3 address-enrich в `run_yandex_city_sweep` (`scrape_pipeline.py:819-823`) запрашивает detail ради извлечения полного адреса из `<title>` (через `yandex_address_backfill._fetch_and_update_one`, прокси `scraper_proxy_url`). Т.е. **fetch-инфра + прокси уже на месте** — не строить с нуля. Минимальный путь: 1. `save_detail_enrichment(db, listing_id, enrichment)` в `yandex_detail.py` (паттерн `cian_detail.py:242`; колонки rooms/area_m2/floor/repair_state/views/agency_*/metro_stations — проверить миграцию 033). 2. В Phase 3 свипа — вместо лёгкого title-only fetch вызвать `YandexDetailScraper.fetch_detail(offer_url)` (полный DetailEnrichment, 17 полей) → `save_detail_enrichment`. Адрес из detail уже включён, так что address-enrich покрывается тем же запросом (1 fetch вместо 2). 3. Для backlog 3952 существующих — отдельный `yandex_detail_backfill` (точный аналог `avito_detail_backfill` #1552: snapshot по area_m2 IS NULL / detail-полям, прокси `YANDEX_PROXY_URL`, budget, scheduler-source + миграция). NB: `yandex_city_sweep` сейчас `enabled=false` (DORMANT, #561) — backfill-task (п.3) даст обогащение независимо от dormant-свипа.
Sign in to join this conversation.
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#1553
No description provided.