# Local Cian backfill scrapers (Playwright, real browser)

Cian блокирует server-IP scraping anti-bot. Эти скрипты запускаются с **локальной машины разработчика**
через SSH-tunnel к prod tradein-postgres — обходят bot detection, используют real Chrome с persistent profile.

## Когда использовать

- Backfill `offer_price_history` для активных Cian listings (history scraper, надёжно)
- Best-effort backfill `external_valuations` для домов где Calculator отдаёт оценку без agent-wizard

## Prerequisites

```bash
pip install playwright "psycopg[binary]" sqlalchemy
python -m playwright install chromium
```

## Setup

### 1. SSH tunnel к tradein-postgres (отдельное окно, держать открытым)

```powershell
$IP = (ssh gendesign 'docker inspect tradein-postgres --format "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}"').Trim()
ssh -L "15433:${IP}:5432" gendesign -N
```

### 2. Env vars (creds из vault `meta/00_credentials.md`)

```powershell
$env:TRADEIN_DB_DSN = "postgresql+psycopg://tradein:<PASSWORD>@localhost:15433/tradein"
$env:COOKIE_ENCRYPTION_KEY = (ssh gendesign 'grep ^COOKIE_ENCRYPTION_KEY= /opt/gendesign/tradein-mvp/.env.runtime | cut -d= -f2').Trim()
```

### 3. Залить Cian cookies (один раз / по мере истечения)

1. Login на cian.ru в обычном Chrome.
2. DevTools → Application → Cookies → www.cian.ru → скопировать `DMIR_AUTH` (httpOnly) + `_CIAN_GK`.
3. Вставить значения в `upload_cookies_local.py` (поля с плейсхолдером `<PASTE_FROM_BROWSER_DEVTOOLS>`).
4. Вставить реальный Cian userId в `ACCOUNT_USER_ID` (найти: DevTools → Network → XHR → `/v1/get-my-id/` → `userId`).
5. Run:

```powershell
python upload_cookies_local.py
```

## Usage

### History backfill (production-ready, не блокируется)

```powershell
python -u playwright_history.py --batch 20 --delay 2 2>&1 | Tee-Object -FilePath cian_history.log
```

- Темп: ~25 listings/min
- Идёт по `id > last_id` ASC pagination
- Записывает в `offer_price_history` (UNIQUE listing_id + change_time)
- Скорость дрейна 5к листингов: ~3-4 часа

### Valuation backfill (best-effort, partial)

```powershell
python -u playwright_valuation.py --batch 10 --delay 5 --wait 8 2>&1 | Tee-Object -FilePath cian_valuation.log
```

- Использует persistent profile `./chrome_profile/` для сохранения сессии между runs
  (переопределяется через `$env:CIAN_PROFILE_DIR`)
- На `not auth` в `--headed` mode — ждёт manual login в открытом окне
- Skip листинги где Cian не отдаёт оценку (~70% таких — новостройки, нет аналогов)

### Если auth теряется

Playwright Chrome имеет другой fingerprint чем твой обычный Chrome → Cian может invalidate сессию. Решения:

- Запустить с `--headed` → login manually в окне.
- Re-upload cookies через `upload_cookies_local.py`.

## Pre-existing knowledge

См. vault `decisions/Decision_Cian_History_Valuation_Activation_May24.md` — full 6-PR sequence
(#523/#525/#530/#535/#539/#543) + open follow-ups.

## Limitations

- Calculator (`external_valuations`) собирается только для домов с готовой оценкой в
  `_cianConfig['valuation-for-agent-frontend'].initialState.estimation`. Полный wizard-flow не автоматизируется.
- `DMIR_AUTH` expires ~30-60 min — нужно периодически перезаливать cookies.
- Не покрывает Cian listings вне нашего SERP (старые не-active, нестандартные region/category).
