144 lines
6.5 KiB
Markdown
144 lines
6.5 KiB
Markdown
# 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. Создать виртуальное окружение и поставить зависимости
|
||
|
||
```powershell
|
||
python -m venv .venv
|
||
.\.venv\Scripts\Activate.ps1
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 2. Получить токен Telegram-бота
|
||
|
||
Уже есть? Отлично. Если нет:
|
||
1. Откройте Telegram, найдите [@BotFather](https://t.me/BotFather).
|
||
2. Отправьте `/newbot`, придумайте имя.
|
||
3. Скопируйте токен вида `123456:ABC-DEF…`.
|
||
|
||
### 3. Создать `.env`
|
||
|
||
```powershell
|
||
Copy-Item .env.example .env
|
||
notepad .env
|
||
```
|
||
|
||
В `.env` вставьте:
|
||
|
||
```
|
||
TG_BOT_TOKEN=ваш_токен_от_botfather
|
||
SCRAPE_INTERVAL_HOURS=4
|
||
ADMIN_CHAT_ID= # опционально — куда слать системные ошибки
|
||
```
|
||
|
||
### 4. Запустить три процесса (в **трёх** разных окнах PowerShell)
|
||
|
||
**Окно 1 — веб-интерфейс:**
|
||
```powershell
|
||
.\.venv\Scripts\Activate.ps1
|
||
python run_web.py
|
||
```
|
||
Откройте http://127.0.0.1:8000
|
||
|
||
**Окно 2 — Telegram-бот:**
|
||
```powershell
|
||
.\.venv\Scripts\Activate.ps1
|
||
python -m app.bot
|
||
```
|
||
|
||
**Окно 3 — фоновый сканер:**
|
||
```powershell
|
||
.\.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.service` → `python run_web.py`
|
||
- `dld-monitor-bot.service` → `python -m app.bot`
|
||
- `dld-monitor-scheduler.service` → `python -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. Опционально — прокси.
|