<p>Необходимо разработать скрипт на языке Python для парсинга (скрапинга) данных с следующих сайтов:</p><ul><li><p><a href="https://sports.ru/">https://sports.ru/</a></p></li><li><p><a href="https://fbref.com/">https://fbref.com/</a></p></li><li><p><a href="https://soccerway.com/">https://soccerway.com/</a> (учитывается как один источник, несмотря на повтор в списке)</p></li><li><p><a href="https://www.whoscored.com/">https://www.whoscored.com/</a></p></li><li><p><a href="https://www.sofascore.com/">https://www.sofascore.com/</a></p></li><li><p><a href="https://www.transfermarkt.com/">https://www.transfermarkt.com/</a></p></li><li><p><a href="https://flashscore.com/">https://flashscore.com/</a></p></li></ul><p>Данные, подлежащие парсингу:</p><ol><li><p><b>Новости:</b> Сбор актуальных новостей по спорту, включая заголовки, даты публикации, краткое описание, полный текст (если доступен), авторов, ссылки на источники и связанные изображения/медиа.</p></li><li><p><b>Каталог:</b> Структурированные данные по спортивным сущностям, включая:</p><ul><li><p>Вид спорта (например, футбол, баскетбол, теннис и т.д.).</p></li><li><p>Страна (географическая привязка лиг, клубов и т.д.).</p></li><li><p>Лиги (названия, сезоны, таблицы результатов).</p></li><li><p>Клубы (названия, составы, статистика).</p></li><li><p>Спортсмены (имена, биографии, статистика, достижения).</p></li><li><p>События (матчи, турниры, даты, результаты, участники, травмы, голы, голевые передачи - все, что есть).</p></li></ul></li></ol><p>Скрипт должен использовать прокси, задержки между запросами для избежания блокировки, и не перегружать серверы.</p><p>На выходе данные должны быть организованы в структурированном виде, аналогичном примеру из приложения.</p><p></p><h2>Требования к скрипту</h2><h3>Технологический стек</h3><ul><li><p><b>Язык программирования:</b> Python (версия 3.8+).</p></li><li><p><b>Библиотеки:</b></p><ul><li><p>Для парсинга: BeautifulSoup4, Scrapy или Selenium (если требуется обработка JavaScript).</p></li><li><p>Для HTTP-запросов: requests или httpx.</p></li><li><p>Для работы с данными: pandas (для манипуляции данными).</p></li><li><p>Для хранения:</p><ul><li><p>Google Sheets: gspread (для интеграции с Google API).</p></li><li><p>PostgreSQL: psycopg2 или SQLAlchemy (для работы с БД).</p></li></ul></li><li><p>Дополнительно: logging для логов, dotenv для хранения конфигураций (API-ключи, credentials).</p></li></ul></li><li><p><b>Хранение данных:</b></p><ul><li><p>Опция 1: Google Sheets – создать/обновить таблицы в Google Sheets (использовать Google Service Account для аутентификации).</p></li><li><p>Опция 2: PostgreSQL – схема БД с таблицами для новостей и каталога (с отношениями foreign keys для связей между сущностями).</p></li><li><p>Скрипт должен поддерживать выбор хранилища через конфигурацию (например, флаг в командной строке или config-файл).</p></li></ul></li><li><p><b>Конфигурация:</b> Все чувствительные данные (API-ключи, DB credentials) хранить в .env файле.</p></li></ul><h3>Функциональные требования</h3><ul><li><p><b>Парсинг новостей:</b></p><ul><li><p>Собрать последние N новостей (N настраивается, по умолчанию 50) с каждого сайта.</p></li><li><p>Извлекать: заголовок, дата, источник, текст, URL, категория (если есть).</p></li><li><p>Обработать пагинацию, если новости на нескольких страницах.</p></li></ul></li><li><p><b>Парсинг каталога:</b></p><ul><li><p>Для каждого сайта собрать иерархические данные по видам спорта, странам, лигам и т.д.</p></li><li><p>Пример структуры:</p><ul><li><p>Таблица "Sports" (вид спорта: ID, название).</p></li><li><p>Таблица "Countries" (страна: ID, название).</p></li><li><p>Таблица "Leagues" (лига: ID, спорт_ID, страна_ID, название, сезон).</p></li><li><p>Таблица "Clubs" (клуб: ID, лига_ID, название, статистика).</p></li><li><p>Таблица "Athletes" (спортсмен: ID, клуб_ID, имя, биография, статистика).</p></li><li><p>Таблица "Events" (событие: ID, лига_ID, дата, участники, результат).</p></li></ul></li><li><p>Глубина парсинга: до уровня детальной страницы (например, профиль спортсмена).</p></li></ul></li><li><p><b>Обработка данных:</b></p><ul><li><p>Очистка данных: удаление HTML-тегов, нормализация текста, обработка дат.</p></li><li><p>Дедупликация: избегать дублей по URL или уникальному ID.</p></li><li><p>Обновление: скрипт должен поддерживать инкрементальный парсинг (только новые данные).</p></li></ul></li><li><p><b>Расписание:</b> Скрипт должен быть адаптирован для запуска по cron (например, ежедневно).</p></li><li><p><b>Логирование и ошибки:</b></p><ul><li><p>Логировать процесс парсинга (успех/ошибки).</p></li><li><p>Обработка исключений: retry при сетевых ошибках, пропуск заблокированных страниц.</p></li></ul></li><li><p><b>Производительность:</b> Задержки между запросами (минимум 1-5 секунд), многопоточность (если применимо, но осторожно, чтобы не блокировать IP).</p></li></ul><h3>Нефункциональные требования</h3><ul><li><p><b>Безопасность:</b> Не хранить пароли в коде; использовать HTTPS.</p></li><li><p><b>Масштабируемость:</b> Скрипт должен работать с большим объемом данных (десятки и сотни тысяч записей).</p></li><li><p><b>Тестирование:</b> Написать unit-тесты для ключевых функций (парсинг, сохранение).</p></li><li><p><b>Документация:</b> <a href="http://README.md">README.md</a> с инструкциями по установке, запуску, конфигурации.</p></li><li><p><b>Совместимость:</b> Работать на Ubuntu.</p></li></ul><p></p><h2>Этапы работ</h2><ol><li><p><b>Анализ и планирование:</b> Изучить сайты, проверить robots.txt, спроектировать структуру данных.</p></li><li><p><b>Разработка скрипта:</b> Написать код для парсинга, интеграции с хранилищем.</p></li><li><p><b>Тестирование:</b> Тест на тестовых данных, проверка на реальных сайтах.</p></li><li><p><b>Деплой и документация:</b> Подготовить репозиторий, инструкции.</p></li></ol><p></p><h2>Критерии приемки</h2><ul><li><p>Скрипт успешно парсит данные с всех сайтов без ошибок.</p></li><li><p>Данные сохраняются в выбранном хранилище в структурированном виде.</p></li><li><p>Структура данных соответствует примеру из приложения (или логической модели, если пример не предоставлен).</p></li><li><p>Скрипт запускается из командной строки с параметрами (например, python <a href="http://script.py">script.py</a> --storage=postgres --limit=50).</p></li><li><p>Нет банов во время сбора данных.</p></li></ul>