ПАРКОВКА (не мержить до прокси): код готов — parser на реальных __SSR_STATE__ путях (productCard.objectInfo/priceInfo.priceHistory/egrnData/houseInfo.info + pricePrediction AVM), orchestrator зеркало avito_detail_backfill, schedule 139 enabled=false. Деплоить нельзя: DomClick card/offer-card за QRATOR reputation-403 на прод mobile-прокси (нужен dedicated residential RU IP). Детали/аудит транспорта — Forgejo issue.
64 lines
4 KiB
PL/PgSQL
64 lines
4 KiB
PL/PgSQL
-- 139_seed_domclick_detail_backfill.sql
|
||
-- Seed row для DomClick Layer B detail-backfill — периодическое обогащение карточек.
|
||
--
|
||
-- !!! DORMANT BY DESIGN !!! enabled = false.
|
||
-- Layer A (domclick_city_sweep, #1979) собирает только базовые SERP-поля. Layer B
|
||
-- дочитывает страницу карточки (.../card/sale__flat__<id>) и обогащает listings:
|
||
-- renovation/repair_state, living/kitchen area, balconies, sale_type, owners_count,
|
||
-- encumbrances, year_built, views, priceHistory.
|
||
--
|
||
-- Транспорт — ТОЛЬКО BrowserFetcher(source="domclick"): карточки за DataDome,
|
||
-- curl_cffi отдаёт 401 (нет curl-fallback). Оркестратор открывает ОДНУ браузер-сессию
|
||
-- на весь прогон. Block (DataDome / fetch-fail) транзиентен → abort после
|
||
-- max_consecutive_blocks с mark_done (НЕ mark_failed); retry следующей ночью через
|
||
-- detail_enriched_at IS NULL. Parse-failure (HTTP 200, но SSR не парсится) → листинг
|
||
-- остаётся необогащённым (rollback) и переотбирается на следующем прогоне.
|
||
--
|
||
-- Capability полностью wired (run_domclick_detail_backfill + trigger_domclick_detail_
|
||
-- backfill_run + dispatch в scheduler.py), но schedule засеян ВЫКЛЮЧЕННЫМ — live-форма
|
||
-- SSR-стейта и поведение DataDome НЕ verified до ручного prod-smoke. ВКЛЮЧАТЬ ВРУЧНУЮ:
|
||
-- UPDATE scrape_schedules SET enabled = true WHERE source = 'domclick_detail_backfill';
|
||
-- Зеркалит yandex_detail_backfill (113) / avito_detail_backfill (112) и dormant-сиды
|
||
-- domclick_city_sweep (122/138).
|
||
--
|
||
-- ЗАВИСИМОСТИ:
|
||
-- - 052_scrape_schedules.sql (таблица + UNIQUE(source)).
|
||
-- - Layer A (#1979 / domclick_city_sweep) должен СНАЧАЛА наполнить listings
|
||
-- source='domklik' (иначе snapshot пуст → no-op mark_done на каждом прогоне).
|
||
-- Idempotent: ON CONFLICT (source) DO NOTHING — безопасно запускать повторно.
|
||
--
|
||
-- Окно 15:00-18:00 UTC (18:00-21:00 МСК) — после avito (09-12) / yandex (12-15) detail
|
||
-- backfills и city sweeps, чтобы не конкурировать за egress на shared mobile proxy.
|
||
-- default_params (консервативно, под DataDome — browser-only транспорт медленный):
|
||
-- batch_size — размер snapshot (SELECT LIMIT) на один прогон.
|
||
-- budget_sec — wall-clock бюджет прогона (сек).
|
||
-- request_delay_sec — пауза между карточками (anti-DataDome).
|
||
-- max_consecutive_blocks — порог последовательных блоков до abort.
|
||
|
||
BEGIN;
|
||
|
||
-- next_run_at = следующее наступление окна (tomorrow + window_start_hour=15h).
|
||
-- При enabled=false get_due_schedules() строку не подхватит, но заполняем по образцу
|
||
-- 122/138: когда оператор включит schedule, next_run_at уже валиден и run не выстрелит
|
||
-- мгновенно (вне окна). AT TIME ZONE 'UTC' фиксирует wall-clock час в UTC независимо
|
||
-- от session TimeZone GUC.
|
||
INSERT INTO scrape_schedules (
|
||
source,
|
||
enabled,
|
||
window_start_hour,
|
||
window_end_hour,
|
||
next_run_at,
|
||
default_params
|
||
)
|
||
VALUES
|
||
(
|
||
'domclick_detail_backfill',
|
||
false, -- DORMANT — enable manually after prod-smoke
|
||
15,
|
||
18,
|
||
((CURRENT_DATE + INTERVAL '1 day') + make_interval(hours => 15)) AT TIME ZONE 'UTC',
|
||
'{"batch_size": 300, "budget_sec": 3600, "request_delay_sec": 8, "max_consecutive_blocks": 5}'::jsonb
|
||
)
|
||
ON CONFLICT (source) DO NOTHING;
|
||
|
||
COMMIT;
|