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

6.5 KiB
Raw Blame History

DLD Monitor

Внутренний инструмент для агентства недвижимости в Дубае: мониторит цены объявлений конкурентов на PropertyFinder.ae и Bayut.com по DLD Permit Number, шлёт уведомления в Telegram при:

  • 📈📉 изменении цены конкурента,
  • удалении объявления (404 / withdrawn),
  • 🆕 появлении нового объявления с тем же permit (новый брокер выставил ту же квартиру).

Архитектура

┌──────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  Web UI      │    │  Scheduler       │    │  Telegram Bot   │
│  (FastAPI)   │    │  (APScheduler)   │    │  (polling)      │
│  add project │    │  every N hours   │    │  /start /check  │
└──────┬───────┘    └────────┬─────────┘    └────────┬────────┘
       │                     │                       │
       └──────────────┬──────┴───────────────────────┘
                     ▼
              ┌────────────────┐
              │   monitor      │
              │   service      │  ← скрапит PF и Bayut, пишет в SQLite
              └────────────────┘
                     │
                     ▼  уведомления в TG конкретному employee

Локальный запуск (Windows)

1. Создать виртуальное окружение и поставить зависимости

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

2. Получить токен Telegram-бота

Уже есть? Отлично. Если нет:

  1. Откройте Telegram, найдите @BotFather.
  2. Отправьте /newbot, придумайте имя.
  3. Скопируйте токен вида 123456:ABC-DEF….

3. Создать .env

Copy-Item .env.example .env
notepad .env

В .env вставьте:

TG_BOT_TOKEN=ваш_токен_от_botfather
SCRAPE_INTERVAL_HOURS=4
ADMIN_CHAT_ID=  # опционально — куда слать системные ошибки

4. Запустить три процесса (в трёх разных окнах PowerShell)

Окно 1 — веб-интерфейс:

.\.venv\Scripts\Activate.ps1
python run_web.py

Откройте http://127.0.0.1:8000

Окно 2 — Telegram-бот:

.\.venv\Scripts\Activate.ps1
python -m app.bot

Окно 3 — фоновый сканер:

.\.venv\Scripts\Activate.ps1
python -m app.scheduler

Первое использование

  1. Откройте бота в Telegram и отправьте /start — он зарегистрирует ваш chat_id.
  2. В веб-UI перейдите в Сотрудники — убедитесь, что вы там есть с ✓ TG.
  3. Нажмите + Новый проект, заполните:
    • Название (например: «Marina Pinnacle 1502, 2BR»)
    • DLD Permit Number (Trakheesi)
    • Тип сделки (продажа/аренда)
    • Владелец = вы
  4. На странице проекта нажмите Проверить сейчас — система найдёт все объявления конкурентов с этим permit на PF и Bayut.
  5. Дальше фоновый сканер сам будет проверять каждые SCRAPE_INTERVAL_HOURS часов и слать уведомления в Telegram.

Команды бота

  • /start — подключить себя как сотрудника (запоминает chat_id)
  • /list — список ваших проектов
  • /check — запустить проверку всех ваших проектов сейчас
  • /whoami — показать свой chat_id

Структура

app/
├── config.py            настройки из .env
├── db.py                SQLAlchemy engine + session
├── models.py            Employee, Project, CompetitorListing, PriceHistory
├── web.py               FastAPI роуты и UI
├── bot.py               Telegram-бот
├── scheduler.py         APScheduler фоновый сканер
├── scrapers/
│   ├── base.py          httpx + парсинг __NEXT_DATA__
│   ├── propertyfinder.py
│   └── bayut.py
├── services/
│   ├── monitor.py       детект изменений, основная бизнес-логика
│   └── notifier.py      отправка в TG
└── templates/           Jinja2 (Bootstrap 5)
data/
└── monitor.db           SQLite (создаётся автоматически)

Перенос на сервер

Когда придёт время — нужно:

  1. Поставить Python 3.11+ на сервер (Linux).
  2. Скопировать репозиторий, pip install -r requirements.txt.
  3. Создать .env.
  4. Поставить три процесса под systemd:
    • dld-monitor-web.servicepython run_web.py
    • dld-monitor-bot.servicepython -m app.bot
    • dld-monitor-scheduler.servicepython -m app.scheduler
  5. Поставить nginx + TLS перед веб-портом (8000).

Возможные проблемы скрапинга

PF/Bayut могут начать блокировать запросы при частых обращениях. Признаки:

  • В логах сканера видны Blocked by site (403/429).
  • Поиск возвращает 0 объявлений, хотя они должны быть.

Что делать:

  1. Уменьшите SCRAPE_INTERVAL_HOURS (реже = меньше риска).
  2. Если не помогает — добавьте Playwright (headless-браузер). Заготовка: pip install playwright && playwright install chromium, затем заменить fetch_html на запуск через Playwright.
  3. Опционально — прокси.