---
name: zemlya_avito_curl_cffi
description: "zemlya-bot тянет рыночные аналоги (Avito+CIAN+Yandex) через curl_cffi, не Playwright; флаги, грабли, фолбэк"
metadata: 
  node_type: memory
  type: project
  originSessionId: d0c6c5aa-4d05-42e2-a1f9-034482b88603
---

zemlya-bot собирает рыночные аналоги через **curl_cffi (TLS-impersonation, без браузера)** как primary с бесшовным фолбэком на Playwright — **все три источника**: Avito, CIAN, Yandex Realty (внедрено 2026-06-24). Флаги в `~/Services/zemlya-bot/.env` (default OFF в коде, в проде ON): `AVITO_CURL_CFFI_PRIMARY=1`, `CIAN_CURL_CFFI_PRIMARY=1`, `YANDEX_CURL_CFFI_PRIMARY=1` (+`*_TIMEOUT`). Market-блок отчёта ускорился в разы (был ~28с — в основном CIAN+Yandex на Playwright).

**По источникам:** Avito — `data-mfe-state`→наш `_walk_initial_data_items`/`_item_from_initial_data` (с coords; Playwright-рендер потерял `__initialData__`). CIAN — `_cianConfig.frontend-serp.initialState.results.offers`→существующий `_parse_offer_json` (с coords). Yandex — SSR-карточки `OffersSerpItem`→`_parse_html` (БЕЗ per-offer coords — их в Yandex SSR нет; `_filter_yandex_by_distance` сохраняет coordless, cadastral.py фильтрует по адресным токенам; + синтез title из площади при мусорном бейдже «+N фото»).

**Грабли (важно):** (1) детект блока НЕ по substring («captcha» грузится JS-ом на каждой CIAN-странице → ложный позитив → вечный фолбэк); критерий блока = «офферы не извлеклись из SSR» (реальная капча не содержит results.offers/OffersSerpItem). (2) Все три curl ТОЛЬКО с прямого RU-IP (`trust_env=False`), через xray → 403. (3) Вставка хелперов между `@bounded` и функцией навешивает декоратор не на ту функцию (корутина + потеря rate-limit) — проверять.

**Точки интеграции:** avito `_fetch_avito_html` (диспетчер) + `_fetch_avito_html_browser`; cian `_collect_search_results` (диспетчер) + `_collect_search_results_browser`; yandex `search_listings` (curl-first в начале). Откат любого источника: его флаг=0 + рестарт. Бэкапы `*.py.bak-curl-cffi-latest`, `.env.bak-*curl-cffi-*` на мини.

**Алерты о поломке (2026-06-24):** бот пишет `data/runtime/ops_health.json` (`bot/services/ops_health.py`: record_market_fallback/record_solver_result), монитор-цикл ops_dashboard (server.py `_check_zemlya_health_alerts`, 60с) читает и шлёт TG (chat 1005954706, токен env `OPS_DASHBOARD_BOT_TOKEN`). Пороги: solver Росреестра ≥2 отказа/час 🔴 (cooldown 45м), источник ≥5 curl-фолбэков/30мин 🟡 (cooldown 60м). TG plain text (parse_mode="" — Markdown падал на `_`/`[`). Бэкапы `*.bak-opshealth`, `server.py.bak-zemlya-health-*`.

**Ускорения «проверить участок» (2026-06-24, доп. сессия), все в проде+проверены живым движком:** (1) `yandex_realty.fetch_offer_details` → curl-first параллельно (было серийный Playwright goto+wait 2.5с/URL ≈7с → ~0.8с); тот же `_parse_offer_page`, фолбэк `_fetch_offer_details_browser`. (2) Капча Росреестра → **Mistral-primary**: `rosreestr_lk._solve_captcha` пробует OmniRoute-Mistral ПЕРВЫМ (raw+blue параллельно), NIM-ансамбль = фолбэк; флаг `CAPTCHA_MISTRAL_PRIMARY=1`, `CAPTCHA_NIM_TIMEOUT=6` (был 12). (3) **Avito-параллель**: `_collect_avito_parallel` собирает все geo+text проходы, тянет через `_fetch_avito_html` с `asyncio.Semaphore(AVITO_PARALLEL_CONCURRENCY=2)`+джиттер, dedup после; fast-path перед серийным циклом, пусто/блок→фолбэк на серийный (не тронут); флаги `AVITO_PARALLEL_PASSES=1`. Гейт-тест 5 локаций: count равен, 0 блоков, 2.4×; live market 78:11 23.5→11.3с. **ГРАБЛИ:** хелперы нельзя вставлять между `@bounded(...)` и `async def` — декоратор навесится на хелпер (корутина, флаг игнор); ловится по `RuntimeWarning: coroutine never awaited`.

**152-ФЗ проверки продавца (банкротство ЕФРСБ), 2026-06-24:** PII субъекта (ФИО/ИНН/регион/результат) НЕ хранится нигде. `seller_check_store.save_check` пишет только счётчики антиабуза (`fio/inn/region/result_json=NULL`). Кнопка «добавить в отчёт» (вшивала PII в PDF) убрана → in-moment проверка. В «📜 История отчётов» (`lk.py`) на каждом PRO-отчёте кнопка «🔍 Продавец: <КН>» (`efrsbchk:{report_id}:{кн}`) → живая перепроверка из истории (идея юзера: раз можно перепроверить — хранить нечего). Проверено live tg-web-e2e. Остаток: на сайте `/reports/[id]` убрать no-op кнопку `addToAi` (compliance уже ок). Бэкапы `.bak-152fz`, `.bak-offercurl`, `.bak-mistralprimary`, `.bak-avitopar`, `.env.bak-speedup`/`.env.bak-avitopar`.

Связано с [[zemlya_web_overview]]. Деталь — Obsidian «Земля без риска check» Changelog/Decisions (D-avito-curl-2026-06-24, D-cian-yandex-curl-2026-06-24).
