gendesign/tradein-mvp/backend/data/sql/204_cian_oblast_sweeps_secondary.sql
bot-backend 6dda48fc6c
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 8s
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 2m40s
fix(tradein/scraper): исключить Верхнюю Пышму из вторички Циана — грязная городская метка
2026-08-02 14:07:56 +03:00

87 lines
7.3 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 204_cian_oblast_sweeps_secondary.sql
-- Включить сбор вторички Циана по 4 областным city-sweep'ам (Свердловская обл.,
-- миграция 179 — nizhniy_tagil/kamensk_uralskiy/pervouralsk/serov).
--
-- ПРОБЛЕМА: _job_cian_city_sweep (scraper_kit.orchestration.scheduler:570) читает
-- newbuilding_only = bool(default_params.get("newbuilding_only", True)) — дефолт True.
-- run_cian_city_sweep (pipeline.py:2436) фильтрует SERP-результат на
-- listing_segment == "novostroyki" ДО save_listings, вторичку отбрасывает
-- (counters.lots_dropped_secondary).
--
-- Дефолт осмыслен для ЕКБ: docstring run_cian_city_sweep прямо говорит, что
-- вторичку авторитетно собирает run_cian_full_load (exhaustive региональный сбор).
-- НО run_cian_full_load (pipeline.py:2790) хардкодит city=EKATERINBURG_CITY_NAME —
-- параметра города там нет вообще, область не покрывает. Итог: областную вторичку
-- Циана не собирает НИКТО (городская развёртка её выбрасывает, full_load туда не
-- ходит) — областные schedule'ы склонированы с ЕКБ (миграция 179) и унаследовали
-- предположение, которое для них неверно.
--
-- Прод-счётчики (scrape_runs.counters, последние runs на 2026-08-02) подтверждают:
-- pervouralsk 55 увидено, 53 выброшено (сохранено 2)
-- kamensk_uralskiy 113 увидено, 108 выброшено (сохранено 5)
-- nizhniy_tagil 184 увидено, 176 выброшено (сохранено 3)
-- verkhnyaya_pyshma 38 увидено, 16 выброшено (сохранено 9) -- см. EXCLUSION ниже
--
-- FIX: newbuilding_only: false для ЧЕТЫРЁХ областных source'ов. cian_city_sweep (ЕКБ,
-- БЕЗ суффикса города) НЕ трогаем — для него дефолт корректен (вторичку ЕКБ
-- собирает cian_full_load), включение дало бы дублирующую нагрузку на источник.
--
-- !!! EXCLUSION: cian_city_sweep_verkhnyaya_pyshma НЕ включён в эту миграцию !!!
-- Верхняя Пышма физически ~15 км от центра Екатеринбурга — geo-проверка по
-- ST_DWithin (координаты listings vs центр города) показала, что 5 из 22 (23%)
-- текущих cian-строк с меткой city="Верхняя Пышма" физически лежат в 15 км от
-- центра ЕКБ, т.е. это загрязнённая городская разметка (sweep по anchor'у В.Пышмы
-- зацепляет краевые екатеринбургские объявления и подписывает их не тем городом).
-- Колонка listings.city — money-critical: её читает asking_to_sold_ratio.py
-- (city-скоуп ASKING vs SOLD стороны, #2583 H2) — неверная метка двигает выкупные
-- цены. При newbuilding_only=false объём cian-строк под меткой В.Пышма вырастет с
-- 22 до нескольких сотен (те же ~38 увидено/16 выброшено за один run, помноженные
-- на число прогонов) — 23%-загрязнение умножилось бы пропорционально.
-- nizhniy_tagil/kamensk_uralskiy/pervouralsk/serov — загрязнение по той же
-- geo-проверке НУЛЕВОЕ (0 из 8/5/2 соответственно физически в ЕКБ) — включать
-- безопасно. cian_city_sweep_verkhnyaya_pyshma будет включён ОТДЕЛЬНОЙ миграцией
-- после починки городской разметки sweep'а (правится параллельно) — НЕ забыт.
--
-- Нагрузка на источник (см. PR description / vault fix-запись для полного разбора):
-- fetch_around_multi_room (providers/cian/serp.py:209) НЕ принимает newbuilding_only/
-- secondary_only — SERP-фаза (все rooms×pages) выполняется ОДИНАКОВО независимо от
-- этого флага. Фильтр в pipeline.py:2436 применяется ПОСЛЕ фетча, ДО save — чисто
-- in-memory отсечение уже оплаченных запросов. HTTP-нагрузка на cian.ru НЕ меняется;
-- меняется только объём save_listings (DB-writes) — на порядок больше СОХРАНЯЕМЫХ
-- строк, не больше запросов к источнику. detail_top_n=10 detail-фетчей тоже не растёт
-- (LIMIT :lim константен, лишь конкурирующий пул кандидатов расширяется).
--
-- Дубли: run_cian_full_load всегда region_code=EKB (city_region_id=4743 через
-- CianScraper() без city_slug), областные sweeps используют CITY_LOCATIONS[<slug>]
-- .cian_region_id (4886/4781/4925/4982 — все != 4743) — SERP-запросы физически
-- разных региональных выдач. dedup_hash = sha256(source|source_id) — глобальный
-- Cian offer_id, ON CONFLICT (dedup_hash) DO UPDATE — даже в теоретическом edge-case
-- совпадения upsert НЕ создаёт дубль-строку.
--
-- listing_segment: providers/cian/serp.py:892 — вторичка получает
-- listing_segment = "vtorichka" (НЕ NULL) → проходит фильтр
-- "listing_segment IS NULL OR listing_segment = 'vtorichka'" в asking_to_sold_ratio.py
-- и buildings_query.py — новые лоты попадут в оценку без доп. кода.
--
-- Мердж jsonb (COALESCE || ...), НЕ перезапись — сохраняет city/radius_m/detail_top_n/
-- enrich_houses/pages_per_anchor/request_delay_sec (см. 179_scrape_schedules_seed_oblast_city_sweeps.sql
-- за текущими прод-значениями). Idempotent: повторный прогон ставит то же значение.
--
-- ЗАВИСИМОСТИ: 052_scrape_schedules.sql (таблица), 179 (seed этих source'ов).
-- deploy order: только миграция — код scheduler.py/pipeline.py НЕ меняется в этом PR,
-- дефолт newbuilding_only=True в коде остаётся (правильный fallback для будущих
-- source'ов без явного default_params override).
BEGIN;
UPDATE scrape_schedules
SET default_params = COALESCE(default_params, '{}'::jsonb)
|| '{"newbuilding_only": false}'::jsonb
WHERE source IN (
'cian_city_sweep_nizhniy_tagil',
'cian_city_sweep_kamensk_uralskiy',
'cian_city_sweep_pervouralsk',
'cian_city_sweep_serov'
);
COMMIT;