# RSS Parser для бизнес-новостей Этот проект представляет собой многопарсерную систему для сбора бизнес-новостей с различных источников, разработанную на Spring Boot с сохранением данных в MongoDB. ## Описание Система включает в себя два парсера: - **Kursiv Media** (`https://kursiv.media/feed/`) - **Kapital.kz** (`https://kapital.kz/rss/`) Оба парсера получают данные из RSS-лент, обрабатывают их и сохраняют в общую базу данных MongoDB с дедупликацией по хэшу. **🔄 Автоматический режим работы:** Оба парсера автоматически запускаются каждые 30 минут (в 0 и 30 минут каждого часа) для обеспечения актуальности данных. ## Технологический стек - **Java 21** - **Spring Boot 3.5.5** - **Spring Data MongoDB** - **Rome** - библиотека для парсинга RSS - **JSoup** - для очистки HTML - **MongoDB** - база данных ## Структура проекта ``` src/main/java/kz/konturai/parser/ ├── ParserApplication.java # Главный класс приложения ├── controller/ │ └── ParserController.java # REST API контроллер ├── model/ │ └── MarketItem.java # Модель данных для MongoDB ├── repository/ │ └── MarketItemRepository.java # Репозиторий для работы с MongoDB └── service/ └── KursivParserService.java # Основной сервис парсинга ``` ## Установка и запуск ### Предварительные требования 1. **Java 21** или выше 2. **MongoDB** (локально или удаленно) 3. **Maven 3.6+** ### Шаги установки 1. **Клонируйте репозиторий:** ```bash git clone cd parser ``` 2. **Установите MongoDB:** - Скачайте и установите MongoDB с официального сайта - Запустите MongoDB сервис - По умолчанию MongoDB работает на порту 27017 3. **Настройте конфигурацию:** Отредактируйте файл `src/main/resources/application.properties`: ```properties # MongoDB Configuration spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 spring.data.mongodb.database=parser_db # RSS Feed URL rss.feed.url=https://kursiv.media/feed/ ``` 4. **Соберите проект:** ```bash ./mvnw clean compile ``` 5. **Запустите приложение:** ```bash ./mvnw spring-boot:run ``` Приложение будет доступно по адресу: `http://localhost:8080` ## API Endpoints ### 1. Запуск парсинга Kursiv Media ```http POST /api/parser/parse/kursiv ``` **Ответ:** ```json { "success": true, "message": "Парсинг Kursiv завершен успешно", "source": "Kursiv", "processedItems": 15, "totalItemsInDb": 25 } ``` ### 2. Запуск парсинга Kapital.kz ```http POST /api/parser/parse/kapital ``` **Ответ:** ```json { "success": true, "message": "Парсинг Kapital завершен успешно", "source": "Kapital", "processedItems": 12, "totalItemsInDb": 37 } ``` ### 3. Запуск парсинга всех источников ```http POST /api/parser/parse/all ``` **Ответ:** ```json { "success": true, "message": "Парсинг всех источников завершен успешно", "kursivProcessed": 15, "kapitalProcessed": 12, "totalProcessed": 27, "totalItemsInDb": 37 } ``` ### 2. Получение статистики ```http GET /api/parser/stats ``` **Ответ:** ```json { "success": true, "totalItems": 25, "message": "Статистика получена успешно" } ``` ### 3. Получение всех записей ```http GET /api/parser/items ``` **Ответ:** ```json { "success": true, "items": [...], "count": 25, "message": "Записи получены успешно" } ``` ### 4. Проверка состояния ```http GET /api/parser/health ``` **Ответ:** ```json { "status": "UP", "service": "RSS Parser System", "timestamp": 1703123456789, "scheduler": "Enabled - runs every 30 minutes" } ``` ### 4.1. Проверка подключения к MongoDB ```http GET /api/parser/health/mongodb ``` **Ответ при успешном подключении:** ```json { "status": "UP", "message": "MongoDB подключение успешно", "totalItems": 37, "timestamp": 1703123456789 } ``` **Ответ при ошибке:** ```json { "status": "DOWN", "message": "Ошибка подключения к MongoDB: Command failed with error 13 (Unauthorized)", "suggestion": "Проверьте учетные данные в application.properties", "timestamp": 1703123456789 } ``` ### 5. Информация о планировщике ```http GET /api/parser/scheduler/info ``` **Ответ:** ```json { "schedulerEnabled": true, "cronExpression": "0 0/30 * * * ?", "description": "Запуск каждые 30 минут (в 0 и 30 минут каждого часа)", "nextRun": "Следующий запуск будет в ближайшие 0 или 30 минут часа" } ``` ## Структура данных в MongoDB Документы сохраняются в коллекции `market_items` со следующей структурой: ```json { "_id": "ObjectId", "source_name": "Kursiv (Бизнес/экономика)", "url": "https://kursiv.media/article/...", "title": "Заголовок новости", "published_at": "2025-01-14T10:30:00", "added_at": "2025-01-14T12:00:00", "raw_text": "Очищенный от HTML текст статьи...", "hash": "sha256_hash_of_url_and_title", "category": "Бизнес", "analytics": { "summary": null, "sentiment": null, "tags": [], "entities": {} } } ``` ## Особенности реализации ### Дедупликация - Каждая запись имеет уникальный хэш, сгенерированный по формуле: `SHA256(url + "::" + title)` - При повторном парсинге существующие записи обновляются (upsert операция) ### Очистка данных - HTML-теги удаляются из текста описания - Даты приводятся к формату `LocalDateTime` - Текстовое содержимое нормализуется ### Обработка ошибок - Логирование всех операций - Graceful handling ошибок парсинга отдельных записей - Продолжение работы при ошибках в отдельных элементах RSS ### Автоматический планировщик - **Автозапуск**: Оба парсера автоматически запускаются каждые 30 минут - **Cron выражение**: `0 0/30 * * * ?` (запуск в 0 и 30 минут каждого часа) - **Параллельная работа**: KursivParserService и KapitalParserService работают независимо - **Логирование**: Все автоматические запуски логируются с эмодзи для удобства мониторинга - **Обработка ошибок**: Ошибки в автоматическом режиме не останавливают планировщик ### Многопарсерная архитектура - **Общая модель данных**: Оба парсера используют одну модель `MarketItem` - **Общая коллекция**: Все новости сохраняются в коллекцию `market_items` - **Дедупликация**: Хэш генерируется одинаково для всех источников - **Разделение источников**: Поле `source_name` позволяет различать источники данных ## Тестирование Запуск тестов: ```bash ./mvnw test ``` Тесты включают: - Проверку парсинга RSS-лент обоих источников - Проверку сохранения в MongoDB - Проверку дедупликации - Проверку структуры данных - Проверку работы планировщика - Проверку многопарсерной архитектуры ## Мониторинг и логирование Приложение использует SLF4J для логирования. Уровень логирования можно настроить в `application.properties`: ```properties logging.level.kz.konturai.parser=DEBUG logging.level.org.springframework.data.mongodb=DEBUG ``` ## Возможные проблемы и решения ### MongoDB требует аутентификацию ``` Command failed with error 13 (Unauthorized): 'Command find requires authentication' ``` **Решение:** 1. Проверьте учетные данные в `application.properties` 2. Убедитесь, что пользователь `parser_user` существует в MongoDB 3. Проверьте права доступа пользователя к базе данных `parser_db` 4. Используйте endpoint `GET /api/parser/health/mongodb` для диагностики **Подробное руководство:** См. файл `MONGODB_TROUBLESHOOTING.md` ### MongoDB не запущен ``` Error: Could not connect to MongoDB ``` **Решение:** Убедитесь, что MongoDB запущен и доступен на указанном хосте и порту. ### RSS-лента недоступна ``` Error: Could not fetch RSS feed ``` **Решение:** Проверьте доступность URL RSS-лент и интернет-соединение. ### Проблемы с кодировкой Если возникают проблемы с кодировкой текста, убедитесь, что в системе установлена правильная локаль. ## Развертывание в продакшене 1. **Настройте переменные окружения:** ```bash export SPRING_DATA_MONGODB_HOST=your-mongodb-host export SPRING_DATA_MONGODB_PORT=27017 export SPRING_DATA_MONGODB_DATABASE=parser_prod ``` 2. **Соберите JAR файл:** ```bash ./mvnw clean package ``` 3. **Запустите приложение:** ```bash java -jar target/parser-0.0.1-SNAPSHOT.jar ``` ## Лицензия Этот проект разработан для внутреннего использования в рамках AI-платформы для маркетинговой аналитики.