- PVSM.RU - https://www.pvsm.ru -
Привет! Сегодня я расскажу о том, как я разработал Telegram-бота для мониторинга цен на Авито. Бот умеет отслеживать изменения цен в объявлениях и уведомлять пользователей об изменениях. В статье я поделюсь всеми этапами разработки, от проектирования до финальной реализации.
Идея создания бота появилась, когда я хотел сделать агента под свои нужды, не буду говорить какие. И дело дошло до автоматизации процесса пользованием авито.
Поиск объявлений по различным параметрам (название, категория, город, ценовой диапазон)
Отслеживание цен в реальном времени
Уведомления при изменении цены (настраиваемый порог изменения)
Управление списком отслеживаемых объявлений
Поддержка нескольких объявлений для каждого пользователя
Python 3.9+
python-telegram-bot 20.7
aiohttp 3.9.1
pydantic 2.5.2
python-dotenv 1.0.0
avito-monitor/
├── bot.py # Основной файл бота
├── avito_api.py # Класс для работы с API Авито
├── config.py # Конфигурация
├── requirements.txt # Зависимости
└── README.md # Документация
python -m venv venv
source venv/bin/activate # для Linux/macOS
pip install python-telegram-bot requests python-dotenv aiohttp beautifulsoup4 pydantic aiofiles
Создаем файл config.py [1] для хранения настроек:
import os
from dotenv import load_dotenv
load_dotenv()
BOT_TOKEN = os.getenv('BOT_TOKEN')
AVITO_CLIENT_ID = os.getenv('AVITO_CLIENT_ID')
AVITO_CLIENT_SECRET = os.getenv('AVITO_CLIENT_SECRET')
AVITO_ACCESS_TOKEN = os.getenv('AVITO_ACCESS_TOKEN')
# Настройки мониторинга
CHECK_INTERVAL = 300 # 5 минут
MAX_ITEMS_PER_USER = 10
PRICE_CHANGE_THRESHOLD = 5 # процент изменения цены
class AvitoAPI:
def __init__(self):
self.base_url = AVITO_API_BASE_URL
self.access_token = AVITO_ACCESS_TOKEN
async def search_items(self, **params):
"""Поиск объявлений"""
return await self._make_request('GET', '/items', params=params)
async def get_item_details(self, item_id: str):
"""Получение деталей объявления"""
return await self._make_request('GET', f'/items/{item_id}')
Важные особенности реализации:
Асинхронные запросы через aiohttp
Система повторных попыток при ошибках
Автоматическое обновление токена
Обработка различных HTTP-статусов
class AvitoBot:
def __init__(self):
self.api = AvitoAPI()
async def start(self, update, context):
"""Обработчик команды /start"""
await update.message.reply_text(
"Привет! Я бот для мониторинга объявлений на Авито..."
)
async def check_prices(self, context):
"""Периодическая проверка цен"""
for user_id, items in user_items.items():
for item_id, last_price in items.copy().items():
try:
item_details = await self.api.get_item_details(item_id)
current_price = float(item_details.get('price', 0))
if self._price_changed_significantly(last_price, current_price):
await self._notify_user(user_id, item_id, last_price, current_price)
except Exception as e:
logger.error(f"Error checking price: {e}")
Поиск реализован в двух форматах:
Простой: пользователь отправляет только поисковый запрос
Расширенный: запрос в формате "Запрос | Категория | Город | Цена от | Цена до"
async def search_items(self, update, query, category=None, location=None,
price_from=None, price_to=None):
try:
# Получаем ID категории и локации если указаны
category_id = await self._get_category_id(category)
location_id = await self._get_location_id(location)
# Выполняем поиск
results = await self.api.search_items(
category_id=category_id,
location_id=location_id,
search_query=query,
price_from=price_from,
price_to=price_to
)
await self._send_search_results(update, results)
except Exception as e:
logger.error(f"Search error: {e}")
Мониторинг реализован через job_queue библиотеки python-telegram-bot:
def main():
application = Application.builder().token(BOT_TOKEN).build()
job_queue = application.job_queue
job_queue.run_repeating(avito_bot.check_prices,
interval=CHECK_INTERVAL, first=10)
Для простоты я использовал словари для хранения данных (In-memory хранилище):
user_items: Dict[int, Dict[str, float]] = {} # user_id -> {item_id: last_price}
В реальном проекте лучше использовать базу данных (например, PostgreSQL или Redis).
Важный момент - правильная обработка ошибок API:
async def _make_request(self, method, endpoint, params=None, data=None,
retry_count=0):
if retry_count >= MAX_RETRIES:
raise Exception(f"Превышено количество попыток")
try:
async with session.request(method, url, params=params,
json=data) as response:
if response.status == 401:
await self.refresh_token()
return await self._make_request(method, endpoint,
params, data, retry_count + 1)
# ... остальная обработка
except aiohttp.ClientError:
await asyncio.sleep(RETRY_DELAY)
return await self._make_request(method, endpoint,
params, data, retry_count + 1)
Добавить поддержку базы данных
Реализовать систему фильтров для уведомлений
Добавить статистику изменения цен
Реализовать поддержку нескольких площадок
Добавить систему подписок на поисковые запросы
Разработка бота была интересным опытом. Основные сложности были связаны с:
Реализацией асинхронных запросов
Правильной организацией системы уведомлений
Исходный код проекта будет доступен на GitHub [2]
P.S. Если у вас есть вопросы или предложения по улучшению бота - пишите в комментариях!
Автор: kbones
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/420742
Ссылки в тексте:
[1] config.py: http://config.py
[2] GitHub: https://github.com/kbonesssss/avito-monitor
[3] Источник: https://habr.com/ru/articles/912836/?utm_source=habrahabr&utm_medium=rss&utm_campaign=912836
Нажмите здесь для печати.