suai-rasp-parser/main.py

247 lines
9.0 KiB
Python
Raw Normal View History

2023-05-13 12:37:15 +03:00
#!/usr/bin/env python3
# TODO
# Распарсить индексник
# Сформировать POST
# Сделать POST
# Забрать результат (готовое расписание)
from bs4 import BeautifulSoup
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
# Реверс инжиринг __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": ""},
{"name": "__VIEWSTATEGENERATOR", "value": ""},
{"name": "__EVENTVALIDATION", "value": ""},
2023-05-13 12:37:15 +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
# Теперь нам надо распарсить список групп и найти нужную
rasp = soup.find('div', {"class": "rasp"})
rasp_div_form = rasp.find('div', {"class": "form"})
2023-05-13 12:37:15 +03:00
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'):
if group.get('value') != "-1":
groups.append({
"name": group.contents[0],
"value": group.get('value')
})
# Формируем 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']
# Заполняем как есть, нам это не интересно
post_data["&ctl00%24cphMain%24ctl06"] = -1
post_data["&ctl00%24cphMain%24ctl07"] = -1
post_data["&ctl00%24cphMain%24ctl08"] = -1
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 16:55:12 +03:00
soup_result = BeautifulSoup(post_result.text, 'html.parser')
# В переменную записываем само расписание, без остальной страницы
rasp_html = soup_result.find('div', {'class', 'result'})
rasp_summary = list()
# Пример rasp_summary
# (
# {
# "date": "Понедельник",
# "value": (
# {
# "time": "1 пара (9:3011:00)",
# "type": "ПР",
# "name": " Прикладная физическая культура (элективный модуль)",
# "profs": (
# "Алексеева С.В. - старший преподаватель"
# ),
# "groups": (
# 1011,
# 1012
# ),
# "place": " Б.Морская 67, ауд. спортзал*",
2023-05-13 17:26:49 +03:00
# "up_or_down": 'none'
# }
# )
# }
# )
2023-05-13 17:26:49 +03:00
# Верхняя - нечетная неделя
# Нижняя - четная неделя
# Верстка сайта на высоте. Придется использовать next_siblings. Хвататься не за что.
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
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':
# какая пара
cur_lesson_time = cur_sibl.text
case 'div':
# Что за пара, препод, место, аудитория
# Верхняя или нижняя?
up_or_down = 'none'
2023-05-13 17:26:49 +03:00
if cur_sibl.find('b', {'class': 'up'}):
up_or_down = 'up'
2023-05-13 17:26:49 +03:00
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'})
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)
# Группы
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
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)
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 17:26:49 +03:00
today_week = date.today().strftime('%U')
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'])