Пошаговая инструкция по созданию автоматизированного конвейера на Airflow, Selenium и Scikit-learn.
Вступление: Автоматизируем рутину
Привет, Хабр! Каждый, кто хоть раз искал подержанную технику, знает эту боль: часы ручного мониторинга Avito, десятки страниц и попытки на глаз определить, адекватна ли цена. Выгодные предложения улетают за минуты.
Я решил подойти к этой задаче как инженер и создать личного ассистента, который бы делал всю грязную работу за меня: 24/7 сканировал Avito, сам оценивал адекватность цены и присылал мне в Telegram только самые сливки.
Так родилась идея проекта Intelligent Deal Finder. В этой статье я познакомлю вас со своим проектом, который решает эту задачу. Эта статья будет ознакомительной.
Часть 1: Архитектура и технологический стек
Любой сложный проект начинается с плана. Я разбил систему на пять логических блоков, которые будут работать в связке:
Парсер: Модуль для сбора сырых данных с Avito.
Хранилище: База данных для накопления объявлений.
Мозг: ML-модель для оценки адекватности цены.
Оркестратор: Система, которая будет запускать все по расписанию.
Уведомитель: Бот для доставки результатов.
Технологический стек выбрал проверенный и надежный: Python, Selenium, PostgreSQL, Scikit-learn, Apache Airflow и Docker.
Часть 2: Сбор и подготовка данных — залог успеха
Основа любой ML-системы — это качественные данные. Мой пайплайн начинается с парсера на Selenium, который заходит на Avito, собирает объявления и передает их дальше.
Ключевой момент — качество данных. Заголовки на Avito могут быть очень грязными. Чтобы не усложнять модель, я принял простое, но эффективное решение: работать только с идеальными заголовками, которых большинство. Я написал строгий фильтр, который пропускает дальше только те объявления, чей заголовок в точности соответствует формату "iPhone [Модель], [Память] ГБ/ТБ".
# Фильтр, который отсекает все лишнее
perfect_title_pattern = r'^iPhone[\w\s]+,\s\d+\s(?:ГБ|ТБ)$'
df = df[df['title'].str.match(perfect_title_pattern, na=False)]
Такой подход позволил сразу отсечь шум и работать с чистым, структурированным датасетом, что, как мы увидим дальше, оказалось решающим фактором.
Часть 3: Создание мозга — предсказательная модель
Имея на руках несколько тысяч идеально отфильтрованных объявлений, я приступил к созданию модели. Гипотеза была проста: на таком чистом рынке цена в первую очередь определяется моделью телефона и объемом его памяти.
Я взял эти два признака, применил к ним стандартный One-Hot Encoding из Pandas и обучил модель RandomForestRegressor из Scikit-learn. Результат оказался на удивление точным:
R² (коэффициент детерминации): 0.91
MAE (средняя абсолютная ошибка): ~4,708 рублей

R² = 0.91 означает, что модель, зная лишь модель и память, уже способна объяснить 91% вариативности цен! Это доказывает, что тщательная фильтрация данных на входе — ключ к успеху.
Часть 4: Ставим все на рельсы — MLOps с Airflow и Docker
Теперь, когда у нас есть работающая модель, нужно заставить всю систему работать автоматически. Для этого я использовал Apache Airflow.
Я создал простой DAG (process_avito_ads) из трех шагов, которые выполняются последовательно:
gather_data_task: Запускает парсер, фильтрует данные по идеальному заголовку и сохраняет их в PostgreSQL.
predict_and_filter_task: Применяет к новым данным нашу обученную модель и отбирает объявления, где предсказанная_цена - реальная_цена больше заданного порога (например, 5000 рублей).
send_notifications_task: Отправляет отфильтрованный список выгодных предложений в Telegram.

Весь проект, включая Airflow, PostgreSQL и сам код приложения, я упаковал в Docker Compose. Это позволяет одной командой docker-compose up --build -d
развернуть всю инфраструктуру на любой машине.
Заключение: Результат и следующие шаги
И вот, ради чего все затевалось. После всей настройки я запустил DAG и через несколько минут получил первое уведомление в Telegram.

Система работает! Она автономно сканирует рынок и доставляет мне только самую ценную информацию, экономя уйму времени.
Этот проект — отличный пример того, как, объединив парсинг, Data Science и MLOps-инструменты, можно создать полезный и работающий продукт. В следующей статье я планирую подробнее рассказать о проблемах, с которыми я сталкивался, о гипотезах и инсайтах.
Весь код проекта доступен на GitHub. Буду рад вашим комментариям и вопросам.