Files
monitoring-pf/SESSION_NOTES.md
2026-06-04 14:55:41 +03:00

6.3 KiB
Raw Blame History

Журнал сессии (2026-05-25)

Что построили

Внутренний мониторинг цен конкурентов на propertyfinder.ae и bayut.com для HOME LIGA REAL ESTATE.

Стек: FastAPI + Jinja2 (Bootstrap 5) + SQLAlchemy/SQLite + APScheduler + python-telegram-bot + httpx/BS4.

Три процесса (каждый — свой .bat-лаунчер):

  • run_web.bat — веб-UI на http://127.0.0.1:8000
  • run_bot.bat — Telegram-бот (polling)
  • run_scheduler.bat — фоновый сканер каждые SCRAPE_INTERVAL_HOURS часов

Эволюция архитектуры

Первая попытка (отвергнута)

Идея: сотрудник вводит DLD Permit Number своего объекта → система автоматически ищет «то же permit» на PF и Bayut → находит объявления конкурентов.

Почему не сработало:

  1. В Дубае каждый брокер получает свой permit на свою публикацию. Два брокера, рекламирующих одну квартиру = два разных permit. Permit не идентифицирует физический объект — он идентифицирует конкретное объявление конкретного брокера.
  2. PF на странице объявления показывает permit картинкой через сервис верификации, не plain text (anti-scraping).
  3. PF search ?q=<permit> — free-text по названию/описанию, не структурированный фильтр.

Финальная архитектура

Manual URL list + опциональные подсказки:

  1. Сотрудник создаёт проект (название, тип сделки, владелец, опц. building/bedrooms/sqft).
  2. На странице проекта вручную вставляет URL объявления конкурента → система делает single-page fetch, парсит __NEXT_DATA__, добавляет в трекинг.
  3. Если указано здание — кнопка «🔍 Подобрать похожие» ищет на PF/Bayut по building + bedrooms и предлагает кандидатов с кнопкой «+ Отслеживать».
  4. Каждые 4 часа фоновый сканер делает refetch каждого отслеживаемого URL → детектит:
    • 📈📉 изменение цены
    • удаление (URL отдаёт 404)
    • ♻️ возвращение из удалённого статуса
  5. Уведомления — в Telegram личкой владельцу проекта.

Модель данных

  • Employee — name, tg_chat_id (опц.), tg_username
  • Project — title, deal_type, owner_id, our_price, building, bedrooms, size_sqft, our_url, dld_permit (все после owner — опционально)
  • CompetitorListing — source (PF|Bayut), external_id, url, current_price, status (active|removed), agent_name, agency_name, first_seen, last_seen
  • PriceHistory — listing_id, price, recorded_at

Как подключиться сотруднику

  1. В TG найти бота → отправить /start.
  2. Отправить /whoami → бот пришлёт chat_id.
  3. В вебе http://127.0.0.1:8000/employees → найти/создать запись → вставить chat_id → Сохранить.

Известные ограничения

  • PF/Bayut могут блокировать при частых запросах (видно как Blocked by site (403/429) в логах). Решение — увеличить интервал; если уже не помогает — добавить Playwright fallback.
  • Подсказки эвристические: ищем по совпадению building name в title + bedrooms-фильтр. Могут попасть «другие квартиры в том же здании» — поэтому добавление в трекинг через ручное подтверждение.
  • Permit как plain text на PF не отдаётся. Если когда-нибудь понадобится — нужен OCR на verification-image.

Что в .env

TG_BOT_TOKEN=<токен от @BotFather>
SCRAPE_INTERVAL_HOURS=4
ADMIN_CHAT_ID=  # опц.

Структура проекта

DLD Permit Number/
├── run_web.bat, run_bot.bat, run_scheduler.bat
├── run_web.py
├── requirements.txt
├── .env (не в git — содержит токен)
├── data/monitor.db (создаётся автоматически)
├── app/
│   ├── config.py     ← settings + резолвит относительные SQLite-пути в абсолютные
│   ├── db.py, models.py
│   ├── web.py        ← FastAPI: CRUD проектов, /listings add/delete, /suggest
│   ├── bot.py        ← /start, /whoami, /list, /check
│   ├── scheduler.py
│   ├── scrapers/{base,propertyfinder,bayut}.py
│   ├── services/{monitor,notifier}.py
│   └── templates/    ← projects_list, project_form, project_detail, suggest, employees, base

Что протестировать в первую очередь

  1. Удалить старый data/monitor.db (схема изменилась).
  2. Запустить три .bat файла.
  3. /start боту → /whoami → chat_id → вписать в Сотрудники.
  4. Создать тестовый проект (Aykon City Tower B, 2BR).
  5. Вставить URL реального объявления конкурента → проверить, что добавилось с ценой/брокером.
  6. Жмякнуть «Подобрать похожие» → посмотреть кандидатов.
  7. Жмякнуть «Проверить сейчас» → если цена не менялась, изменений не будет (это нормально); для теста алертов можно поменять цену в БД руками или подождать реального изменения.