Сервис мониторит RSS- и HTML-источники модной индустрии (Vogue, Elle, Harper's Bazaar, Buro 24/7 и др.), находит новые статьи и рассылает их подписчикам в Telegram.
appпо расписанию (cron, раз в 20 минут) обходит список источников:- для сайтов с RSS — парсит фид напрямую (
feedparser); - для сайтов без RSS — сначала пробует быстрый разбор HTML через
BeautifulSoup, и только если результатов мало — подключает headless-браузер (Playwright), потому что часть сайтов рендерит контент на клиенте.
- для сайтов с RSS — парсит фид напрямую (
- Новые статьи (по уникальной ссылке) сохраняются в Postgres и рассылаются всем подписчикам бота.
bot— отдельный процесс с Telegram-ботом наaiogram: пользователь пишет/start, егоchat_idсохраняется в БД, и дальше он получает уведомления о новых статьях.
┌──────────┐ cron /20min ┌────────────┐ ┌────────────┐
│ app │ ─────────────▶ │ парсинг │ ─────▶ │ Postgres │
│ (парсер) │ │ RSS / HTML │ │ │
└──────────┘ └────────────┘ └─────┬──────┘
│
┌──────────┐ /start (chat_id) │
│ bot │ ◀─────────────────────────────── Telegram ────┘
│ │ ─────────────▶ рассылка новых статей подписчикам
└──────────┘
- Python 3.10, asyncio
aiogram— Telegram-ботfeedparser,BeautifulSoup,Playwright— парсинг RSS/HTMLasyncpg— асинхронный доступ к Postgresaiolimiter— ограничение частоты рассылки в Telegram (защита от rate limit)- Docker / Docker Compose, cron внутри контейнера
dbmate— миграции БД
app/
main.py точка входа парсера
rss_parser.py разбор RSS-источников
html_parser.py разбор HTML-источников (BS4 → Playwright fallback)
save_article.py дедупликация статей и рассылка в Telegram
urls.py списки источников
db/migrations/ SQL-миграции (dbmate)
crontab.txt расписание парсера
bot/
bot.py Telegram-бот, обработка /start
logger_config.py общий логгер для app и bot
Понадобятся Docker, Docker Compose и dbmate (для миграций).
cp .env.example .env
# впишите BOT_TOKEN — токен, выданный @BotFather
make build # поднимет контейнеры и прогонит миграцииОстановить:
make downМиграции применяются с хоста отдельной командой (
dbmate), а не самим контейнеромapp, поэтому при первом стартеappможет пару раз залогироватьrelation "..." does not existдо того, как миграции успеют накатиться — это ожидаемо и самоустраняется на следующем цикле cron.
| Переменная | Назначение |
|---|---|
BOT_TOKEN |
токен Telegram-бота |
DATABASE_URL |
строка подключения к Postgres, которую использует приложение |
POSTGRES_* |
параметры для инициализации контейнера с Postgres |
RSS- и HTML-адреса перечислены в app/urls.py. Для HTML-источника без RSS нужно дополнительно описать CSS-селекторы карточки/заголовка/ссылки в HTML_SITE_CONFIG в app/html_parser.py.
Логи парсера и бота пишутся в /app/app.log внутри соответствующего контейнера:
docker compose exec app cat /app/app.logMIT, см. LICENSE.
