Асинхронный парсер структуры Тверского государственного университета (ТвГУ), собирающий и нормализующий информацию о факультетах, институтах и кафедрах из нескольких публичных источников.
Проект предназначен для получения, сопоставления и экспорта структурированных данных о подразделениях ТвГУ
(факультеты, институты, кафедры, руководство, контакты, адреса, группы и т.д.)
в формате JSON.
В университете нет единого формального API, содержащего всю необходимую информацию, поэтому парсер агрегирует данные сразу из нескольких источников:
- HTML-страниц сайта ТвГУ
- публичного API абитуриентского раздела
- незадокументированного API расписаний
Выкладываю проект, чтобы у студентов и разработчиков была возможность получать целостные и согласованные данные о структуре университета для своих сервисов и приложений.
Проект не привязан к конкретному интерфейсу и может использоваться как:
- CLI-утилита
- источник данных для сайтов и ботов
- backend-компонент для каталогов факультетов и кафедр
- Загрузка и агрегация данных о структуре ТвГУ из 4 разных источников
- Парсинг и нормализация информации о:
- факультетах и институтах
- кафедрах
- руководителях (ФИО с разбиением на части)
- контактных данных (email, телефоны, добавочные номера)
- адресах и почтовых индексах
- официальных сайтах
- описаниях подразделений
- видеоматериалах (если присутствуют на странице)
- учебных группах и кодах факультетов
- Корректная обработка:
- «грязного» HTML (неразрывные пробелы, нестабильные разделители)
- отсутствующих или частично заполненных данных
- скрытых блоков и вложенной разметки
- Фильтрация служебных и неактуальных структур
- Проверка консистентности данных между всеми источниками
- Асинхронная загрузка
- Экспорт в JSON (с форматированием или без)
Парсер объединяет информацию из следующих источников:
- Страница структуры ТвГУ
https://tversu.ru/sveden/struct - Страница с описаниями факультетов и институтов
https://tversu.ru/pages/2182 - API абитуриентского раздела
https://abiturient.tversu.ru/api/catalog/faculties - Незадокументированное API групп расписаний
https://timetable.tversu.ru/api/v3/groups
Агрегация этих источников позволяет получить наиболее подробные сведения о каждой структуре (либо я не знаю нужного эндпоинта).
- Структура HTML-страниц и API может меняться со стороны ТвГУ
- Парсер опирается на текущую DOM-структуру и семантику данных
- Некоторые поля могут отсутствовать или быть заполнены частично
- При несовпадении данных между источниками парсер намеренно падает с ошибкой, чтобы избежать экспорта неконсистентных данных
- Часть структур сознательно исключается из обработки (аспирантура, служебные подразделения и т.п.)
Если выкидывание ошибок вам не нравится: правьте код с соблюдением лицензии MIT
- Python 3.10+
- Зависимости:
aiohttpbeautifulsoup4
Установка зависимостей:
pip install aiohttp beautifulsoup4python -m tvgu_structs_parserВ этом режиме данные загружаются, но никуда не сохраняются: бесполезно
python -m tvgu_structs_parser --output teachers.json --prettify--output structs.json – Файл для экспорта в JSON формате
--prettify – Форматировать вывод (с отступами и переносом строк)
--warnings – Выводить в консоль предупреждения (например, при невалидных группах)
python -m tvgu_structs_parser --output-auto --output-directory dataВ этом случае название файла будет иметь такой вид: structs-YYYY-MM-DD.json и находиться он будет в папке data
Используйте функцию get_all_tvgu_structs() – просто вызывайте её (не забудьте await) и получите список всех структур ТвГУ
Формат возвращаемого значения: list[TvGUStruct] – список датаклассов с описанием факультета или института
Выходной JSON имеет следующую структуру:
[
{
"name": "Факультет прикладного питона и фундаментального си",
"shortname": "ХимТехМедШкед",
"description": "Ну короче факультет, описание, привлечение абитуриентов и т.п.",
"code": "ППиФС",
"type": "faculty",
"boss_name": "Иван",
"boss_surname": "Иванов",
"boss_patronymic": "Контрструкович",
"address": "г. Тверь, ул. Жигарева, 5",
"postal_code": "170000",
"website": "https://besttvgu.ru",
"email": "bestdevelopment@gmail.com",
"phones": ["1234567890", "0987654321"],
"phones_additional_codes": ["123", null],
"video_url": "https://...",
"departments": [
{
"name": "Кафедра бла-бла-бла",
"struct_name": "Институт экономики и управления",
"boss_name": "Александр",
"boss_surname": "Воробьёв",
"boss_patronymic": "Михайлович",
"boss_jobs": [
"Зав. кафедрой"
],
"address": "г. Тверь, ул. 2-я Грибоедова, 22",
"postal_code": "170021",
"website": null,
"email": "hahahahahaha@tversu.ru",
"division_clause_url": "https://www.youtube.com/watch?v=HIcSWuKMwOw",
"phones": [
"88005553535"
],
"phones_additional_codes": [
null
]
}
],
"groups": [
"ПМиК-16",
"ПМиК-11"
]
}
]Некоторые поля могут быть пустыми или отсутствовать в зависимости от данных на сайте: смотрите аннотации типов
TvGUStructвnormalizer.py
Свободное использование Не несу ответственности за изменения в API или структуре данных со стороны ТвГУ
Если ты используешь парсер или он тебе помог, то прошу лишь поставить звёздочку репозиторию)
P.S. – снова)