2023-05-13 12:37:15 +03:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
# TODO
|
|
|
|
|
# Распарсить индексник
|
|
|
|
|
# Сформировать POST
|
|
|
|
|
# Сделать POST
|
|
|
|
|
# Забрать результат (готовое расписание)
|
|
|
|
|
|
|
|
|
|
from bs4 import BeautifulSoup
|
2023-05-13 13:22:11 +03:00
|
|
|
|
import re
|
2023-05-13 13:31:36 +03:00
|
|
|
|
import requests
|
2023-05-13 17:26:49 +03:00
|
|
|
|
import sys
|
2023-05-13 12:37:15 +03:00
|
|
|
|
|
|
|
|
|
useragent = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0"
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2023-05-13 17:26:49 +03:00
|
|
|
|
print("Hello, fucker, what is ur name?")
|
|
|
|
|
fucker_name = input()
|
2023-05-13 17:38:59 +03:00
|
|
|
|
if fucker_name == "":
|
|
|
|
|
fucker_name = "Тебя"
|
2023-05-13 17:26:49 +03:00
|
|
|
|
print("Your group?")
|
|
|
|
|
stud_group = input()
|
|
|
|
|
if stud_group == '':
|
|
|
|
|
print("Введи группу")
|
|
|
|
|
sys.exit(1)
|
2023-05-13 16:55:12 +03:00
|
|
|
|
init_url = "https://guap.ru/rasp/"
|
|
|
|
|
init_headers = {
|
|
|
|
|
'User-Agent': useragent
|
|
|
|
|
}
|
|
|
|
|
init_html = requests.get(init_url, headers=init_headers)
|
|
|
|
|
|
|
|
|
|
soup = BeautifulSoup(init_html.text.strip(), 'html.parser')
|
2023-05-13 12:37:15 +03:00
|
|
|
|
|
2023-05-13 12:51:37 +03:00
|
|
|
|
# Реверс инжиринг __doPostBack
|
|
|
|
|
#
|
|
|
|
|
# <script type="text/javascript">
|
|
|
|
|
# //<![CDATA[
|
|
|
|
|
# var theForm = document.forms['Form1'];
|
|
|
|
|
# if (!theForm) {
|
|
|
|
|
# theForm = document.Form1;
|
|
|
|
|
# }
|
|
|
|
|
# function __doPostBack(eventTarget, eventArgument) {
|
|
|
|
|
# if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
|
|
|
|
|
# theForm.__EVENTTARGET.value = eventTarget;
|
|
|
|
|
# theForm.__EVENTARGUMENT.value = eventArgument;
|
|
|
|
|
# theForm.submit();
|
|
|
|
|
# }
|
|
|
|
|
# }
|
|
|
|
|
# //]]>
|
|
|
|
|
# </script>
|
|
|
|
|
|
|
|
|
|
# _doPostBack
|
|
|
|
|
# @param eventTarget
|
|
|
|
|
# @param eventArgument
|
|
|
|
|
# E.g.:
|
|
|
|
|
# <a href="javascript:__doPostBack('ctl00$cphMain$ctl09','')">
|
|
|
|
|
# Показать расписание
|
|
|
|
|
# Я не видел, чтобы 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 - АУДИТОРИЯ (ЗАЛ)
|
|
|
|
|
|
2023-05-13 12:37:15 +03:00
|
|
|
|
# Криптохуйню ищем
|
|
|
|
|
cryptshits = (
|
|
|
|
|
{"name": "__EVENTTARGET", "value": ""},
|
|
|
|
|
{"name": "__EVENTARGUMENT", "value": ""},
|
|
|
|
|
{"name": "__VIEWSTATE", "value": ""},
|
2023-05-13 12:51:37 +03:00
|
|
|
|
{"name": "__VIEWSTATEGENERATOR", "value": ""},
|
|
|
|
|
{"name": "__EVENTVALIDATION", "value": ""},
|
2023-05-13 12:37:15 +03:00
|
|
|
|
)
|
2023-05-13 12:51:37 +03:00
|
|
|
|
|
2023-05-13 12:37:15 +03:00
|
|
|
|
for i in cryptshits:
|
|
|
|
|
val = soup.find('input', {"id": i['name']})
|
2023-05-13 16:55:12 +03:00
|
|
|
|
i['value'] = val.get('value')
|
2023-05-13 12:37:15 +03:00
|
|
|
|
|
2023-05-13 13:22:11 +03:00
|
|
|
|
# Теперь нам надо распарсить список групп и найти нужную
|
|
|
|
|
|
|
|
|
|
rasp = soup.find('div', {"class": "rasp"})
|
|
|
|
|
|
|
|
|
|
rasp_div_form = rasp.find('div', {"class": "form"})
|
2023-05-13 12:37:15 +03:00
|
|
|
|
|
2023-05-13 13:22:11 +03:00
|
|
|
|
groups = list()
|
|
|
|
|
group_keyword = "группа:"
|
2023-05-13 12:51:37 +03:00
|
|
|
|
|
2023-05-13 13:22:11 +03:00
|
|
|
|
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'):
|
|
|
|
|
if group.get('value') != "-1":
|
|
|
|
|
groups.append({
|
2023-05-13 13:26:39 +03:00
|
|
|
|
"name": group.contents[0],
|
|
|
|
|
"value": group.get('value')
|
2023-05-13 13:22:11 +03:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
# Формируем POST data
|
|
|
|
|
post_data = dict()
|
|
|
|
|
# Заполняем дату криптохуйней
|
|
|
|
|
for i in cryptshits:
|
|
|
|
|
post_data[i['name']] = i['value']
|
|
|
|
|
# Ищем группу
|
|
|
|
|
for group in groups:
|
|
|
|
|
if group['name'] == stud_group:
|
2023-05-13 16:55:12 +03:00
|
|
|
|
post_data['ctl00%24cphMain%24ctl05'] = group['value']
|
2023-05-13 13:22:11 +03:00
|
|
|
|
# Заполняем как есть, нам это не интересно
|
|
|
|
|
post_data["&ctl00%24cphMain%24ctl06"] = -1
|
|
|
|
|
post_data["&ctl00%24cphMain%24ctl07"] = -1
|
|
|
|
|
post_data["&ctl00%24cphMain%24ctl08"] = -1
|
2023-05-13 12:51:37 +03:00
|
|
|
|
|
2023-05-13 16:55:12 +03:00
|
|
|
|
post_headers = {"Content-Type": "application/x-www-form-urlencoded", 'User-Agent': useragent}
|
|
|
|
|
post_url = "https://guap.ru/rasp/?g={}".format(post_data['ctl00%24cphMain%24ctl05'])
|
|
|
|
|
post_result = requests.post(post_url, data=post_data, headers=post_headers)
|
2023-05-13 13:52:45 +03:00
|
|
|
|
|
|
|
|
|
# Парсим полученные данные
|
2023-05-13 16:55:12 +03:00
|
|
|
|
soup_result = BeautifulSoup(post_result.text, 'html.parser')
|
2023-05-13 13:52:45 +03:00
|
|
|
|
|
2023-05-13 15:09:58 +03:00
|
|
|
|
# В переменную записываем само расписание, без остальной страницы
|
|
|
|
|
rasp_html = soup_result.find('div', {'class', 'result'})
|
2023-05-13 13:52:45 +03:00
|
|
|
|
|
|
|
|
|
rasp_summary = list()
|
|
|
|
|
# Пример rasp_summary
|
|
|
|
|
# (
|
|
|
|
|
# {
|
2023-05-13 15:09:58 +03:00
|
|
|
|
# "date": "Понедельник",
|
2023-05-13 13:52:45 +03:00
|
|
|
|
# "value": (
|
|
|
|
|
# {
|
|
|
|
|
# "time": "1 пара (9:30–11:00)",
|
|
|
|
|
# "type": "ПР",
|
|
|
|
|
# "name": "– Прикладная физическая культура (элективный модуль)",
|
|
|
|
|
# "profs": (
|
|
|
|
|
# "Алексеева С.В. - старший преподаватель"
|
|
|
|
|
# ),
|
|
|
|
|
# "groups": (
|
|
|
|
|
# 1011,
|
|
|
|
|
# 1012
|
|
|
|
|
# ),
|
|
|
|
|
# "place": "– Б.Морская 67, ауд. спортзал*",
|
2023-05-13 17:26:49 +03:00
|
|
|
|
# "up_or_down": 'none'
|
2023-05-13 13:52:45 +03:00
|
|
|
|
# }
|
|
|
|
|
# )
|
|
|
|
|
# }
|
|
|
|
|
# )
|
2023-05-13 17:26:49 +03:00
|
|
|
|
# Верхняя - нечетная неделя
|
|
|
|
|
# Нижняя - четная неделя
|
2023-05-13 15:09:58 +03:00
|
|
|
|
# Верстка сайта на высоте. Придется использовать next_siblings. Хвататься не за что.
|
|
|
|
|
|
|
|
|
|
rasp_html_inside = rasp_html.find('div')
|
|
|
|
|
# Это будет ужасно...
|
|
|
|
|
cur_day = ""
|
|
|
|
|
cur_lesson = ""
|
|
|
|
|
day_iterator = 0
|
2023-05-13 15:43:57 +03:00
|
|
|
|
groups = list()
|
2023-05-13 15:09:58 +03:00
|
|
|
|
for cur_sibl in rasp_html_inside.find_next_siblings():
|
|
|
|
|
tag_type = cur_sibl.name
|
|
|
|
|
|
|
|
|
|
match tag_type:
|
|
|
|
|
case 'h2':
|
|
|
|
|
# Header, пропускаем
|
|
|
|
|
print(cur_sibl.text)
|
|
|
|
|
case 'h3':
|
|
|
|
|
# День недели
|
|
|
|
|
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':
|
|
|
|
|
# какая пара
|
2023-05-13 16:11:05 +03:00
|
|
|
|
cur_lesson_time = cur_sibl.text
|
2023-05-13 15:09:58 +03:00
|
|
|
|
case 'div':
|
|
|
|
|
# Что за пара, препод, место, аудитория
|
|
|
|
|
|
2023-05-13 15:43:57 +03:00
|
|
|
|
# Верхняя или нижняя?
|
|
|
|
|
up_or_down = 'none'
|
2023-05-13 17:26:49 +03:00
|
|
|
|
if cur_sibl.find('b', {'class': 'up'}):
|
2023-05-13 15:43:57 +03:00
|
|
|
|
up_or_down = 'up'
|
2023-05-13 17:26:49 +03:00
|
|
|
|
if cur_sibl.find('b', {'class': 'dn'}):
|
2023-05-13 15:43:57 +03:00
|
|
|
|
up_or_down = 'down'
|
|
|
|
|
|
|
|
|
|
# Тип пары (лекция)
|
|
|
|
|
lesson_type = cur_sibl.find('b', {'class': ''})
|
2023-05-13 15:09:58 +03:00
|
|
|
|
|
|
|
|
|
# Что за пара
|
2023-05-13 15:43:57 +03:00
|
|
|
|
lesson_name = lesson_type.next_sibling
|
2023-05-13 15:09:58 +03:00
|
|
|
|
|
2023-05-13 15:43:57 +03:00
|
|
|
|
# Препод
|
|
|
|
|
preps = list()
|
|
|
|
|
preps_block = cur_sibl.find('span', {'class': 'preps'})
|
2023-05-13 16:55:12 +03:00
|
|
|
|
if preps_block is not None:
|
|
|
|
|
for prep in preps_block.findAll('a'):
|
|
|
|
|
preps.append(prep.text)
|
2023-05-13 15:09:58 +03:00
|
|
|
|
|
2023-05-13 15:43:57 +03:00
|
|
|
|
# Группы
|
|
|
|
|
groups = list()
|
|
|
|
|
group_block = cur_sibl.find('span', {'class': 'groups'})
|
|
|
|
|
for group in group_block.findAll('a'):
|
|
|
|
|
groups.append(group.text)
|
2023-05-13 15:09:58 +03:00
|
|
|
|
|
|
|
|
|
# место, аудитория
|
2023-05-13 15:43:57 +03:00
|
|
|
|
place = cur_sibl.find('em')
|
2023-05-13 15:09:58 +03:00
|
|
|
|
|
|
|
|
|
# Итого, пишем в rasp_summary
|
2023-05-13 16:11:05 +03:00
|
|
|
|
temp_list_para = {
|
|
|
|
|
"time": cur_lesson_time,
|
|
|
|
|
"type": lesson_type.text,
|
|
|
|
|
"name": lesson_name,
|
|
|
|
|
"profs": preps,
|
|
|
|
|
"groups": groups,
|
|
|
|
|
"place": place.text,
|
|
|
|
|
"up_or_down": up_or_down
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
temp_dict = {
|
|
|
|
|
"date": cur_day,
|
|
|
|
|
"value": temp_list_para
|
|
|
|
|
}
|
|
|
|
|
rasp_summary.append(temp_dict)
|
2023-05-13 15:09:58 +03:00
|
|
|
|
case _:
|
|
|
|
|
print('wtf')
|
2023-05-13 13:31:36 +03:00
|
|
|
|
|
2023-05-13 16:55:12 +03:00
|
|
|
|
from datetime import date
|
|
|
|
|
import locale
|
2023-05-13 17:26:49 +03:00
|
|
|
|
|
2023-05-13 16:55:12 +03:00
|
|
|
|
locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8")
|
|
|
|
|
today_weekday = date.today().strftime('%A')
|
2023-05-13 20:10:45 +03:00
|
|
|
|
today_week = int(date.today().strftime('%U'))
|
2023-05-13 17:26:49 +03:00
|
|
|
|
print("Сегодня {}, {} ебали на:".format(today_weekday, fucker_name))
|
2023-05-13 16:55:12 +03:00
|
|
|
|
for para in rasp_summary:
|
|
|
|
|
if para['date'] == today_weekday:
|
2023-05-13 17:26:49 +03:00
|
|
|
|
if para['value']['up_or_down'] == 'up' and today_week % 2 != 0:
|
|
|
|
|
print(para['value']['type'], para['value']['name'])
|
|
|
|
|
elif para['value']['up_or_down'] == 'down' and today_week % 2 == 0:
|
|
|
|
|
print(para['value']['type'], para['value']['name'])
|
|
|
|
|
elif para['value']['up_or_down'] == 'none':
|
|
|
|
|
print(para['value']['type'], para['value']['name'])
|