Пошаговая инструкция по созданию автоматизированного конвейера на Airflow, Selenium и Scikit-learn.

Вступление: Автоматизируем рутину

Привет, Хабр! Каждый, кто хоть раз искал подержанную технику, знает эту боль: часы ручного мониторинга Avito, десятки страниц и попытки на глаз определить, адекватна ли цена. Выгодные предложения улетают за минуты.

Я решил подойти к этой задаче как инженер и создать личного ассистента, который бы делал всю грязную работу за меня: 24/7 сканировал Avito, сам оценивал адекватность цены и присылал мне в Telegram только самые сливки.

Так родилась идея проекта Intelligent Deal Finder. В этой статье я познакомлю вас со своим проектом, который решает эту задачу. Эта статья будет ознакомительной.

Часть 1: Архитектура и технологический стек

Любой сложный проект начинается с плана. Я разбил систему на пять логических блоков, которые будут работать в связке:

  1. Парсер: Модуль для сбора сырых данных с Avito.

  2. Хранилище: База данных для накопления объявлений.

  3. Мозг: ML-модель для оценки адекватности цены.

  4. Оркестратор: Система, которая будет запускать все по расписанию.

  5. Уведомитель: Бот для доставки результатов.

Технологический стек выбрал проверенный и надежный: PythonSeleniumPostgreSQLScikit-learnApache 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) из трех шагов, которые выполняются последовательно:

  1. gather_data_task: Запускает парсер, фильтрует данные по идеальному заголовку и сохраняет их в PostgreSQL.

  2. predict_and_filter_task: Применяет к новым данным нашу обученную модель и отбирает объявления, где предсказанная_цена - реальная_цена больше заданного порога (например, 5000 рублей).

  3. send_notifications_task: Отправляет отфильтрованный список выгодных предложений в Telegram.

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

Заключение: Результат и следующие шаги

И вот, ради чего все затевалось. После всей настройки я запустил DAG и через несколько минут получил первое уведомление в Telegram.

Система работает! Она автономно сканирует рынок и доставляет мне только самую ценную информацию, экономя уйму времени.

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

Весь код проекта доступен на GitHub. Буду рад вашим комментариям и вопросам.