Всем добрый день!

В этом году я являюсь выпускником 11 класса и, соответственно, человеком, который сдает ЕГЭ. Результаты экзаменов обычно приходят не раньше, чем через неделю. При этом их можно отслеживать как минимум на 3 ресурсах: Госуслуги, Checkege (единый портал) и на сайтах региональных центров обработки информации - РЦОИ. Тенденция последних лет показывает, что раньше всего результаты появляются на региональных ресурсах.
Поэтому, находясь в томительном ожидании, я решил проанализировать сайт РЦОИ Пермского края. Важно отметить, что в каждом регионе эти сайты различаются, поэтому универсального рецепта здесь нет, никакой документации для разработчиков или публичного API тем более.

Форма для запроса результатов
Форма для запроса результатов

Для получения результатов экзамена необходимо знать только серию и номер паспорта. После их ввода результаты представляются в виде обезличенной таблицы.

Таблица с результатами
Таблица с результатами

Порадовало отсутствие капч и каких-либо антифрод систем на сайте, это безусловно облегчит задачу.

Приступим

Сначала я нашел PHP-скрипт, которому передаются номер и серия паспорта экзаменуемого, но при попытке просто передать данные была получена ошибка "Сессия не создана". Оказывается, страница ввода паспортных данных генерирует некоторый "rhash", который необходимо передать в параметрах скрипту, при этом каждый такой сгенерированный хеш можно использовать только один раз, иначе мы рискуем получить ошибку "Сессия на активна".

Так как разрабатывать бота я решил на Python, то запросы тестировались сразу с использованием библиотеки requests.

>>> params = {'rhash': '581db7b0f8dd2ed7482c7674b49f1bea5ff6d806978f', 'ds':'', 'dn':''}
>>> r = requests.get('https://kraioko.perm.ru/utils/results/loadstudentresults.php', params=params)
>>> r.text
<table width=100%>\r\n <tr bgcolor=linen class=headline>\r\n            <td>Предмет\r\n            <td>Тестовый балл\t\t\t\r\n            <td>Результат\r\n            <td>Год<tr bgcolor=white><td><a id='id5CD1D809-54C4-4CBF-8CEF-ADE985B98146'>Русский язык</a><td>93\r\n        <td>Экзамен сдан\r\n        <td>2023
длинный и малочитамемый код таблицы

Всё, необходимые данные были получены. Далее я выполнил парсинг с помощью классических инструментов - BeautifulSoup4 и lxml.
В результате таблица была упакована в такой удобочитаемый вид:

[['Русский язык', '93', 'Экзамен сдан', '2023'], ['Математика', '90', 'Экзамен сдан', '2024'], ['Информатика', '93', 'Экзамен сдан', '2024']]

Самая нетривиальная задача этого проекта была решена, теперь осталось создать бота с использованием aiogram и добавить базу данных sqlite3 для хранения пользовательских данных.

Телеграм Бот

Сразу после запуска бота пользователю необходимо сохранить паспортные данные, затем получение результатов сводится к вводу одной команды /check. Для сохранения конфиденциальности, несмотря на то, что сохраняются только 10 цифр из паспорта, Telegram ID пользователя хешируется и добавляется в таблицу БД именно в таком виде. При запросе результатов происходит хеширование ID пользователя и запрос паспортных данных на основании этого хеш-значения.

Список результатов, полученных от бота
Список результатов, полученных от бота

Получение результатов теперь доступно, оставалось самое главное - мониторинг результатов и уведомления об их изменениях на сайте. Ради этого пришлось пожертвовать конфиденциальностью, т.к. необходимо точное сопоставление "Пользователь и его Chat ID - Паспортные данные" для того, чтобы отправить изменения в случае их появления.
Чтобы не сохранять в БД полный список результатов для каждого пользователя, я решил хешировать эти данные с помощью SHA-256 и хранить это значение в таблице (изначально я использовал длину полученной таблицы, как маркер для изменений, но стало очевидно, что баллы по предметам могут быть изменены без добавления новых строк).
Затем я написал асинхронную функцию, которая получает результаты, хеширует их и сверяет с сохраненным значением в БД. При изменениях хеш перезаписывается, а пользователю приходит уведомление. Функция выполняется раз в 10 минут, но это значение может быть изменено администратором бота без перезапуска (были реализованы несколько админских команд).

Оповещение об изменении результатов
Оповещение об изменении результатов
Команда для мониторинга
Команда для мониторинга

Развертывание и интеграция

Далее я создал Dockerfile и использовал имеющийся у меня шаблон пайплайна Jenkins, чтобы развернуть это все на небольшом домашнем сервере с локальным инстансом Gitea. Конечно, был адаптирован не весь функционал ресурса (например, возможность просмотра разбалловки по заданиям конкретного экзамена), но достаточно того, что пользователи теперь могут получать уведомления о результатах в числе первых.

Основной функционал бота (в том числе и мониторинг результатов) был реализован за одни сутки. В дальнейшем, перед публикацией, производился рефакторинг кода и разделение его по файлам :).

Репозиторий: https://github.com/gberdyshev/KraiokoPerm_bot
Бот: https://t.me/kraioko_results_bot

Комментарии (3)


  1. semenInRussia
    13.07.2024 13:23
    +1

    А для других городов будет работать?

    (10й класс, мне на будущее. Я не понимаю пока как вообще баллы в ЕГЭ раздаются)

    А, ну я как понял нет


    1. gberdyshev Автор
      13.07.2024 13:23
      +2

      Нет, но если есть желание, можно попробовать найти и поковырять сайт РЦОИ для своего региона. Есть универсальный бот для Checkege, но туда приходит обычно чуть позже (на день примерно).


    1. 1dntfkngcare
      13.07.2024 13:23
      +1

      точно знаю что @EgeCheckBot В 2021 работал по всей стране и каким-то волшебным образом он получал результаты ещё до того, как они были опубликованы где-либо. Щас вроде чекнул, вроде он и щас работает, но уже не выдаёт мои баллы.