feat(scrapers): yandex detail-enrichment — save + ночной backfill через прокси (part of #1553) #1554
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
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#1554
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/yandex-detail-backfill"
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?
Проблема (#1553)
Yandex detail-данные не сохранялись НИКУДА:
YandexDetailScraper.fetch_detailпарсит 17 полей, ноsave_detail_enrichmentотсутствовал, и detail не вызывался в свипе. На проде (verified): yandexarea_m223%,living/kitchen0%,repair_state1%.Фикс
Реализован yandex detail save + ночной backfill для 3952 существующих (аналог avito
avito_detail_backfill#1552):yandex_detail.py— новыйsave_detail_enrichment(db, listing_id, e): UPDATE listings (COALESCE для базовых rooms/area/floor/repair/description/address — не затирает непустое; metro_stations/photo_urls → jsonb; agency_*/views_total_yandex/publish_date_relative). psycopg v3 CAST. Возвращает bool.app/tasks/yandex_detail_backfill.py(new) —run_yandex_detail_backfill: snapshotsource='yandex' AND detail_enriched_at IS NULL(приоритет active+свежие), budget guard, run-lifecycle.YandexDetailScraper.fetch_detail= plain httpx БЕЗ прокси → captcha/shell на datacenter-IP. Поэтому fetch идёт черезcurl_cffi AsyncSession(impersonate=chrome120, proxies=scraper_proxy_url)(зеркало рабочегоyandex_address_backfill), затемYandexDetailScraper().parse(html, offer_url)(чистая функция). Captcha→parse None.consecutive_none++; послеmax_consecutive_blocks→ abort +mark_done(не failed; объявление остаётся NULL → повтор след. прогон). reset на успехе. db.rollback() на ошибке.scheduler.py—trigger_yandex_detail_backfill_run+ dispatch elif.data/sql/113_yandex_detail_backfill.sql—ADD COLUMN IF NOT EXISTSphoto_urls/newbuilding_url/newbuilding_id (остальные 14 полей уже имеют колонки по 002/011/033); seed scrape_schedules enabled=true окно 12-15 UTC (не пересекается с avito_detail_backfill 9-12),batch_size=800 budget_sec=3600 delay=5 max_consecutive_blocks=5, idempotent.Проверки
uv run pytest(полный suite, оба CI-deselect): 1821 passed, 2 deselected, 0 failed.ruff check+ruff format --check: clean.Scope / остаётся в #1553
Этот PR = yandex save + backfill (даёт обогащение 3952 сразу, через
yandex_detail_backfillкрон, независимо от dormantyandex_city_sweep). НЕ входит (follow-up #1553): интеграция detail-стадии в активный свип + ciankitchen_area_m2(minor).Миграция 113 (110-112 уже в main).
- scheduler.py: исправлен stale-комментарий yandex_detail_backfill (был: «YandexDetailScraper httpx, no proxy layer»; теперь: fetch via curl_cffi chrome120 + scraper_proxy_url, parse via YandexDetailScraper.parse) - yandex_detail_backfill.py: outer except — сообщение лога изменено на «save/iteration error for listing_id=%d» чтобы отличать save-ошибку от fetch/parse-None путей (run_id убран — он менее важен в этом scope)