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
87 lines
7.3 KiB
PL/PgSQL
87 lines
7.3 KiB
PL/PgSQL
-- 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;
|