# Price Monitor Bot

Telegram-бот на aiogram 3, который отслеживает цены на товары по ссылкам и
уведомляет пользователя, когда цена меняется.

## Возможности

- Добавление монитора: команда `/add <ссылка>` или просто отправка ссылки боту
- Список активных мониторов: `/list` (с кнопкой удаления под каждым)
- Удаление монитора: `/remove <id>`
- Фоновая проверка всех активных мониторов раз в час (настраивается)
- Хранение данных в SQLite (`monitor.db`)

## Установка

```bash
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -r requirements.txt
playwright install chromium
```

На некоторых Linux-дистрибутивах для headless Chromium дополнительно
нужны системные библиотеки:

```bash
playwright install-deps chromium
```

(на Ubuntu/Debian можно через `sudo`; если хостинг без sudo-доступа —
уточни у провайдера или ставь в Docker-образ с уже готовыми зависимостями).

## Настройка

1. Получи токен бота у [@BotFather](https://t.me/BotFather).
2. Скопируй `.env.example` в `.env` и вставь токен:

```bash
cp .env.example .env
```

```
BOT_TOKEN=123456:AAExampleTokenHere
```

## Запуск

```bash
python bot.py
```

## Как это работает

- `price_parser.py` — получает HTML страницы двумя способами: сначала быстрый
  обычный HTTP-запрос через `aiohttp`; если сайт блокирует его (403/429/498)
  или это заведомо "тяжёлый" домен (Wildberries, Ozon), используется headless-
  браузер через `browser_fetcher.py`. Дальше из готового HTML цена и название
  извлекаются тремя способами по очереди: JSON-LD разметка schema.org →
  meta/itemprop-теги → регулярка по тексту страницы.
- `browser_fetcher.py` — headless Chromium через Playwright. Держит один
  запущенный браузер на всё время работы бота и открывает новые вкладки
  (контексты) под каждый запрос — так быстрее и экономнее по памяти, чем
  поднимать браузер заново на каждую проверку.
- `db.py` — вся работа с SQLite (aiosqlite), таблица `monitors`.
- `bot.py` — обработчики команд + фоновая asyncio-задача `check_prices_loop`,
  которая раз в `CHECK_INTERVAL_SECONDS` (по умолчанию 3600 сек = 1 час)
  обходит все активные мониторы и сравнивает цену.

### Важно про Wildberries, Ozon и подобные маркетплейсы

Даже с headless-браузером и "антидетект" настройками (скрытие
`navigator.webdriver`, реалистичный User-Agent, локаль и т.п.) крупные
маркетплейсы могут по-прежнему иногда блокировать запросы — они анализируют
не только заголовки, но и поведенческие паттерны, TLS/Canvas-фингерпринтинг,
частоту запросов с одного IP и т.д. Это снижает вероятность блокировки, но
не гарантирует стабильную работу на 100%. Если блокировки продолжаются
часто, обычно помогает:
- увеличить паузы между проверками одного и того же сайта;
- использовать резидентные/мобильные прокси вместо серверного IP хостинга
  (у датацентровых IP репутация хуже, их банят агрессивнее);
- в критичных случаях — платные антидетект-сервисы (ScraperAPI, ZenRows,
  Bright Data и т.п.), которые уже решают эту проблему на своей стороне.

## Возможные доработки

- Разбить фоновую проверку на батчи с ограничением параллелизма (asyncio.Semaphore),
  если мониторов станет много — особенно важно с браузером, чтобы не открывать
  десятки вкладок Chromium одновременно
- Хранить историю цен отдельной таблицей для графиков
- Поддержка нескольких валют с конвертацией в одну для сравнения
- Ротация прокси для проблемных доменов
