Привет, Хабр. Это моя первая статья, и сегодня я хочу рассказать вам про свой первый модуль на python. Называется он dnevnikru. Я написал его для облегчения работы с сайтом дневника. Работает модуль по принципу парсера, а не получает данные через API.
Идея написать такой модуль пришла мне после идеи написать телеграм бота для просмотра оценок и домашних заданий из Дневника.ру, так как смотреть успеваемость в телефоне с браузера неудобно, а функционал приложения платный.
Почему не через API?
Это сделано потому что Администрация Дневника отказывает разработчикам в предоставлении доступа к API.
Конечно, функционал этого модуля не сравнится с функционалом, предоставляемым официальным API. Я добавил только самые необходимые функции, о которых я расскажу ниже.
Как этим пользоваться?
Сам модуль находится в github репозитории. Также, я залил модуль на PyPi. Для установки нужно прописать в терминале:
pip install dnevnikru
Мануал по использованию и описание методов есть на wiki странице
Доступные методы
На момент написания статьи, я реализовал 5 методов.
homework - Получение домашних заданий за определенный период
marks - Получение оценок за четверть (семестр)
searchpeople - Поиск людей по Вашей школе (Среди учителей, учеников, работников. Можно искать по имени, классу, ФИО)
birthdays - Дни рождения людей из Вашей школы
week - Возвращает результаты недели (расписание, посещаемость, пройденные темы и так далее)
Подробнее о методах:
homework
Принимает 4 необязательных параметра
datefrom - С какой даты отобразить Д/З (в формате dd.mm.yyyy). По умолчанию стоит текущий день.
dateto - До какой даты отобразить Д/З (в формате dd.mm.yyyy). По умолчанию +10 дней к datefrom
days - На сколько дней вперед отобразить (Используется когда ни datefrom, ни dateto не указаны, либо когда указан только datefrom)
studyYear - учебный год (Используется для просмотра домашних заданий прошлых лет)
Возвращает словарь с домашними заданиями.
Пример
from dnevnikru import Dnevnik
from pprint import pprint
dn = Dnevnik(login="login", password="password")
pprint(dn.homework(days=2))
{'homeworkCount': 9,
'homework': (('Алгебра и НА', 'п.1', 'Сегодня 2 урок'),
('Алгебра и НА', 'п.2', 'Сегодня 2 урок'),
('Геометрия', 'п.52', 'Сегодня 4 урок'),
('Инф. и ИКТ', '§1.8.3, с.92-94', 'Сегодня 5 урок'),
('Инф. и ИКТ', '§1.8.3, с.94-95', 'Сегодня 5 урок'),
('Алгебра и НА',
'п.2 № № 8, 11, 12,16,чет 19 (2)',
'21 октября 2021 3 урок'),
('Геометрия',
'№ 456 разобрать№ 455, 457, 462',
'21 октября 2021 4 урок'),
('Рус. язык',
'Пар.79-80.Словарный диктант.Приложение 2.(абажур-алюминий).',
'21 октября 2021 5 урок'),
('Род.язык',
'Итоговое по первому направлению!Сочинение!Принести черновик!',
'21 октября 2021 6 урок'))}
marks
Принимает 2 необязательных параметра
index - Год обучения. По умолчанию вернется текущий год
period - Период. Если ничего не передать - вернется текущий период.
Возвращает кортеж списков с оценками, количеством пропусков, пропусков по болезни и вообще все данные, которые отображает таблица
Пример
from dnevnikru import Dnevnik
from pprint import pprint
dn = Dnevnik(login="login", password="password")
pprint(dn.marks())
(['1', 'Алгебра и НА', '555', '0', '6', '3', '2', ''],
['2', 'Англ. язык', '555', '0', '6', '2', '4,5', ''],
['3', 'Биология', '', '0', '0', '0', '', ''],
['4', 'Геометрия', '555', '0', '4', '3', '4', ''],
['5', 'Инф. и ИКТ', '555', '0', '10', '6', '', ''],
['6', 'ИПД', '555', '0', '2', '1', '', ''],
['7', 'История', '555', '0', '3', '2', '3', ''],
['8', 'Литература', '555', '0', '15', '2', '', ''],
['9', 'ОБЖ', '555', '0', '1', '1', '5', ''],
['10', 'Реш. физ. задач', '555', '0', '2', '1', '', ''],
['11', 'Реш.задач по матем', '555', '0', '2', '1', '', ''],
['12', 'Род.язык', '555', '0', '1', '1', '', ''],
['13', 'Рус. язык', '555', '0', '2', '1', '4', ''],
['14', 'Физика', '555', '0', '14', '6', '3,5', ''],
['15', 'Физкультура', '555', '0', '8', '3', '', ''],
['16', 'Химия', '555', '0', '4', '1', '', ''])
Отметки находятся только во 2 элементе (Начиная с 0 элемента)
searchpeople
Принимает 3 необязательных параметра
group - Группа среди которой нужно искать людей. По умолчанию пустое значение, будет искать среди всех (all). Доступные группы - 'all', 'students', 'staff', 'director', 'management', 'teachers', 'administrators'
name - Поиск по имени. Можно вводить имя, фамилию, ФИО. Разные форматы.
grade - Поиск по классу. Опять же, можно использовать разные форматы. Например: "11Б", "8 Г", "9.1" - для тех, у кого в школе не буквы, а цифры.
Возвращает словарь с людьми
Пример
from dnevnikru import Dnevnik
from pprint import pprint
dairy = Dnevnik("login", "password")
birthdays = dairy.birthdays(day=9, month=5)
{'peopleCount': 8,
'people': (('З***а Александра Сергеевна', 'Ученик'),
('К***в Александр Юрьевич', 'Родитель'),
('К***а Юлия Александровна', 'Ученик'),
('К***в Андрей Александрович', 'Родитель'),
('К***а Елена Александровна', 'Родитель'),
('С***я Ольга Александровна', 'Родитель'),
('С***а Александр Иванович', 'Ученик'),
('С***а Иван Александрович', 'Родитель'))}
Фамилии скрыл в целях конфиденциальности
birthdays
Принимает 3 необязательных параметра
day (int) - день (по умолчанию текущая дата)
month (int) - месяц
group - Группа среди которой нужно искать людей. По умолчанию пустое значение, будет искать среди всех (all). Доступные группы - 'all', 'students', 'staff', 'class'
Пример
from dnevnikru import Dnevnik
from pprint import pprint
dairy = Dnevnik("login", "password")
birthdays = dairy.birthdays(day=9, month=5)
{'birthdaysCount': 3,
'birthdays': ('П***в Александр Павлович',
'К***а Софья Михайловна',
'П***в Ярослав Иванович')}
week
Позволяет получить результаты недели (информация берется от сюда http://dnevnik.ru/currentprogress/choose?userComeFromSelector=True)
Принимает 2 необязательных параметра:
info - тип результатов (Доступные типы - "themes", "attendance", "marks", "schedule", "homeworks") (По умолчанию schedule, т.е. расписание)
weeks - Сдвиг по неделям (По умолчанию 0, т.е. текущая неделя. Для прошедших недель используется отрицательное число)
Пример
from dnevnikru import Dnevnik
from pprint import pprint
dairy = Dnevnik("login", "password")
schedule = dairy.week()
{'student': 'Владимир Путин, МБОУ СОШ № 1, 7-А, 2021 / 2022, с 18.10 по '
'24.10',
'schedule': {'понедельник': ('Реш. физ. задач',
'Англ. язык',
'Реш.задач по матем',
'Химия',
'Физика'),
'вторник': ('Физика',
'Физика',
'Литература',
'Литература',
'История',
'Физкультура'),
'среда': ('История',
'Алгебра и НА',
'Физкультура',
'Геометрия',
'Инф. и ИКТ',
'Инф. и ИКТ'),
'четверг': ('Физика',
'Физика',
'Алгебра и НА',
'Геометрия',
'Рус. язык',
'Род.язык'),
'пятница': ('Англ. язык',
'ИПД',
'Алгебра и НА',
'Алгебра и НА',
'Литература',
'Физкультура'),
'суббота': ('Физика',
'Англ. язык',
'ОБЖ',
'Инф. и ИКТ',
'Инф. и ИКТ'),
'воскресенье': ()}}
Итог
Для меня эта библиотека стала первым опытом написания «открытых» проектов, поэтому, если Вы обнаружили какие-то баги/некачественный код/ и прочее, что можно исправить - сообщайте. Я буду только рад улучшить свой проект. Всем удачи.
UPD: Библиотека периодически обновляется, поэтому актуальная информация доступна на wiki странице библиотеки
Комментарии (18)
StepanSkryabin
01.10.2021 04:19О круто, сам уже пару месяцев парсер делаю для этого поделия (dnevnik.ru). Какие планы на развитие проекта?
paracosm17 Автор
01.10.2021 07:48Пока что буду фиксить некачественный код по советам Хабровчан из комментариев. Потом буду придумывать новые методы и расширять функционал. Вот мне там ниже рассказали о /currentprogress/choose?userComeFromSelector=True
Попробую с помощью этого какой-нибудь новый метод написать. Например, для просмотра результатов недели
StepanSkryabin
01.10.2021 12:54я надеюсь пулл-реквесты на гитхабе приветствуются? а то я хотел бы поучаствовать в разработке (насколько моих знаний хватит).
Trig3G
01.10.2021 07:05Реализация конечно никуда не годится.
И самое главное там же есть доступ просто к гос. услуге по информации успеваемости /currentprogress/choose?userComeFromSelector=True открывается в плоскую страницу, также имеет все оценки и информацию о ДЗ. Парсить её куда проще.
paracosm17 Автор
01.10.2021 07:06Не знал об этой услуге. Спасибо, что рассказали. Попробую добавить метод для просмотра результатов недели
SkillZQ
01.10.2021 10:40Не могу утверждать, но скорее всего приложение дневник ру общается с сервером по нормальному апи. Если нужно - могу посмотреть и скинуть запросы
StepanSkryabin
01.10.2021 13:00И претензия к тексту статьи - неплохо бы код оформить "как код", т. е. с подсветкой синтаксиса, и вообще мне кажется не очень удобным расположение описания методов в спойлерах.
protobuf
Возможно лучше воспользоваться assert'ом?
Невероятно
:wow:
И ещё 100500 пунктов...
В общем, реализация - :crap:, а идея хорошая
paracosm17 Автор
Спасибо за фидбэк! Буду исправлять
shibanovan
Не обращайте внимания, человек выше просто самоутвержиться за ваш счет решил.
Спасибо за то что выложили в открытый доступ - тоже хотел парсить, но у них там структура конечно адская для парсинга, я открыл - посмотрел и закрыл)
protobuf
Вчера думал, что автор троллирует всех, но потом узнал, что это 12ти летний парень, который код скорее всего пишет впервые. Порицаю себя за вчерашний коментарий. Автор большой молодец! Желаю чтобы автор не переставал развиваться и всё у него прокнуло с библиотекой
ivankuzin
Отличное работа, сам занимался подобным в начале карьеры разработчика.
А для того, чтобы писать красивый код, с эффективным использованием функционала языка, советую прочитать пару книг по разработке, я бы выбрал "A byte of Python". По моему мнению - лучшая для новичка.
amalchuk
Насчёт assert'ов возражу, при отключённом режиме отладки (например, при запуске с ключом -O2) assert'ы не будут делать ничего от слова совсем.