#!/usr/bin/env python3 # TODO # Распарсить индексник # Сформировать POST # Сделать POST # Забрать результат (готовое расписание) from bs4 import BeautifulSoup import re import requests html_sample = """ Расписание занятий на весенний семестр 2022/23 учебного года - Сборка: 22 февраля
Санкт-Петербургский государственный университет аэрокосмического приборостроения

 

Расписание занятий на весенний семестр 2022/23 учебного года (Сборка: 22 февраля)

Сегодня: ▲ суббота, 13 мая 2023 года, верхняя нечетная (37) учебная неделя.

группа: преподаватель: аудитория:  
Показать расписание|Очистить
- верхняя (нечетная) неделя
- нижняя (четная) неделя

Л - лекция
ПР - практическое занятие или семинар
ЛР - лабораторные занятия
КП - курсовой проект
КР - курсовая работа

Расписание для группы - 1012

Понедельник

2 пара (11:10–12:40)

Л – Информационно-статистическая теория измерений – Б.Морская 67, ауд. 12-12
ПР – Основы проектирования измерительно-вычислительных комплексов – Б.Морская 67, ауд. 12-07

3 пара (13:00–14:30)

ЛР – Интеллектуальные системы – Б.Морская 67, ауд. 52-08
Преподаватель: Добровольская А.А. - ассистентГруппа: 1012

4 пара (15:00–16:30)

ЛР – Базовые технологии приборостроения – Б.Морская 67, ауд. 13-07
Преподаватель: Окин П.А. - старший преподавательГруппа: 1012

7 пара (20:10–21:40)

ПР – Основы тестирования ПО – Дистант, ауд.
Преподаватель: Загураева М.В. - ассистентГруппы: 1011; 1012

Вторник

1 пара (9:30–11:00)

Л – Базовые технологии приборостроения – Б.Морская 67, ауд. 14-06г

2 пара (11:10–12:40)

ПР – Информационно-статистическая теория измерений – Б.Морская 67, ауд. 12-10

4 пара (15:00–16:30)

Л – Интеллектуальные системы – Б.Морская 67, ауд. 52-18

Среда

3 пара (13:00–14:30)

Л – Основы проектирования измерительно-вычислительных комплексов – Б.Морская 67, ауд. 13-15

4 пара (15:00–16:30)

ЛР – Цифровые вычислительные устройства и микропроцессоры – Б.Морская 67, ауд. 12-06

5 пара (16:40–18:10)

Л – Безопасность жизнедеятельности – Б.Морская 67, ауд. 32-03
ПР – Безопасность жизнедеятельности – Б.Морская 67, ауд. 14-58

6 пара (18:30–20:00)

Пятница

3 пара (13:00–14:30)

Л – Авиационные приборы и измерительно-вычислительные комплексы – Б.Морская 67, ауд. 12-10
Преподаватель: Тихомиров М.Е. - доцентГруппы: 1011; 1012

4 пара (15:00–16:30)

Л – Моделирование процессов и систем – Б.Морская 67, ауд. 52-42
ЛР – Основы проектирования измерительно-вычислительных комплексов – Б.Морская 67, ауд. 12-07

5 пара (16:40–18:10)

ПР – Моделирование процессов и систем – Б.Морская 67, ауд. 12-07

6 пара (18:30–20:00)

ЛР – Моделирование процессов и систем – Б.Морская 67, ауд. 12-06

Суббота

1 пара (9:30–11:00)

2 пара (11:10–12:40)

Л – Цифровые вычислительные устройства и микропроцессоры – Б.Морская 67, ауд. 13-14
ЛР – Авиационные приборы и измерительно-вычислительные комплексы – Б.Морская 67, ауд. 53-10

3 пара (13:00–14:30)

ЛР – Безопасность жизнедеятельности – Б.Морская 67, ауд. 14-05
Преподаватель: Гущина Е.А. - ассистентГруппа: 1012

4 пара (15:00–16:30)

ПР – Цифровые вычислительные устройства и микропроцессоры – Б.Морская 67, ауд. 12-06
КП – Авиационные приборы и измерительно-вычислительные комплексы – Б.Морская 67, ауд. 12-07

6 пара (18:30–20:00)

Л – Основы тестирования ПО – Дистант, ауд.
""" useragent = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0" stud_group = "1011" if __name__ == '__main__': print("Hello, fucker") soup = BeautifulSoup(html_sample, 'html.parser') # print(soup.prettify()) # print(soup.findAll('группа:')) # print(soup.getText()) # crypted_shit = soup.find('div', class_="aspNetHidden") print() # Реверс инжиринг __doPostBack # # # _doPostBack # @param eventTarget # @param eventArgument # E.g.: # # Показать расписание # Я не видел, чтобы eventArgument заполнялось, поэтому оставляем пустым # Т.е. просто заполняет 2 переменные # Реверс POST запроса # Передается вот это: # &__EVENTARGUMENT= # &__VIEWSTATE=%2FwEPDwUKLTkzNTgzNzI3Ng9kFgJmD2Q..... # &__VIEWSTATEGENERATOR=3EAAC6F7 # &_EVENTVALIDATION=%2FwEdAIgLxA5dNdvuvMP6V.... # &ctl00%24cphMain%24ctl05=2 - НОМЕР ГРУППЫ # &ctl00%24cphMain%24ctl06=-1 - ПРЕПОД # &ctl00%24cphMain%24ctl07=-1 - АУДИТОРИЯ (МЕСТО) # &ctl00%24cphMain%24ctl08=-1 - АУДИТОРИЯ (ЗАЛ) # Криптохуйню ищем cryptshits = ( {"name": "__EVENTTARGET", "value": ""}, {"name": "__EVENTARGUMENT", "value": ""}, {"name": "__VIEWSTATE", "value": ""}, {"name": "__VIEWSTATEGENERATOR", "value": ""}, {"name": "__EVENTVALIDATION", "value": ""}, ) for i in cryptshits: val = soup.find('input', {"id": i['name']}) i['value'] = val.get('value') # print(cryptshits) # Теперь нам надо распарсить список групп и найти нужную rasp = soup.find('div', {"class": "rasp"}) rasp_div_form = rasp.find('div', {"class": "form"}) groups = list() group_keyword = "группа:" for i in rasp_div_form.find_all('span'): group_html_block = i.find(string=re.compile(group_keyword)) if group_html_block is None: break else: for group in group_html_block.parent.findAll('option'): # print(group.contents, group.get('value')) if group.get('value') != "-1": groups.append({ "name": group.contents[0], "value": group.get('value') }) # print(group_html_block) # print(group_html_block.parent) # print(groups) # Формируем POST data post_data = dict() # Заполняем дату криптохуйней for i in cryptshits: post_data[i['name']] = i['value'] # Ищем группу for group in groups: if group['name'] == stud_group: post_data['ctl00%24cphMain%24ctl05=2'] = group['value'] # Заполняем как есть, нам это не интересно post_data["&ctl00%24cphMain%24ctl06"] = -1 post_data["&ctl00%24cphMain%24ctl07"] = -1 post_data["&ctl00%24cphMain%24ctl08"] = -1 # print(post_data) post_headers = {"Content-Type": "application/x-www-form-urlencoded"} post_url = "https://guap.ru/rasp/?g=2" # FIXME представляем в голове, что мы получили страницу post_result = html_sample # post_result = requests.post(post_url, data=post_data, headers=post_headers) # Парсим полученные данные soup_result = BeautifulSoup(post_result, 'html.parser') # В переменную записываем само расписание, без остальной страницы rasp_html = soup_result.find('div', {'class', 'result'}) # print(result_html.prettify()) rasp_summary = list() # Пример rasp_summary # ( # { # "date": "Понедельник", # "value": ( # { # "time": "1 пара (9:30–11:00)", # "type": "ПР", # "name": "– Прикладная физическая культура (элективный модуль)", # "profs": ( # "Алексеева С.В. - старший преподаватель" # ), # "groups": ( # 1011, # 1012 # ), # "place": "– Б.Морская 67, ауд. спортзал*", # "up_or_down": None # } # ) # } # ) # Верстка сайта на высоте. Придется использовать next_siblings. Хвататься не за что. # print(rasp_html.prettify()) rasp_html_inside = rasp_html.find('div') # Это будет ужасно... cur_day = "" cur_lesson = "" day_iterator = 0 groups = list() for cur_sibl in rasp_html_inside.find_next_siblings(): tag_type = cur_sibl.name # print(tag_type, cur_sibl.text) match tag_type: case 'h2': # Header, пропускаем print(cur_sibl.text) case 'h3': # День недели # print(cur_sibl.text) if cur_day == '' and cur_day != cur_sibl.text and day_iterator == 0: cur_day = cur_sibl.text elif cur_day != '' and cur_day != cur_sibl.text: day_iterator += 1 cur_day = cur_sibl.text case 'h4': # какая пара # print(cur_sibl.text) cur_lesson = cur_sibl.text case 'div': # Что за пара, препод, место, аудитория # Верхняя или нижняя? up_or_down = 'none' if cur_sibl.find('b', {'class':'up'}): up_or_down = 'up' if cur_sibl.find('b', {'class':'dn'}): up_or_down = 'down' # Тип пары (лекция) lesson_type = cur_sibl.find('b', {'class': ''}) # Что за пара lesson_name = lesson_type.next_sibling # Препод preps = list() preps_block = cur_sibl.find('span', {'class': 'preps'}) for prep in preps_block.findAll('a'): preps.append(prep.text) # Группы groups = list() group_block = cur_sibl.find('span', {'class': 'groups'}) for group in group_block.findAll('a'): groups.append(group.text) # место, аудитория place = cur_sibl.find('em') # Итого, пишем в rasp_summary print('sdfsdf ', day_iterator, cur_day, cur_lesson, up_or_down, lesson_type.text, place.text, groups, preps) # rasp_summary[cur_day][cur_lesson] = cur_sibl # print(cur_sibl.text) case _: print('wtf') print(rasp_summary)