suai-rasp-parser/main.py

247 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# TODO
# Распарсить индексник
# Сформировать POST
# Сделать POST
# Забрать результат (готовое расписание)
from bs4 import BeautifulSoup
import re
import requests
import sys
useragent = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0"
if __name__ == '__main__':
fucker_name = "Тебя"
print("Hello, fucker, what is ur name?")
fucker_name = input()
print("Your group?")
stud_group = input()
if stud_group == '':
print("Введи группу")
sys.exit(1)
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')
# Реверс инжиринг __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 - АУДИТОРИЯ (ЗАЛ)
# Криптохуйню ищем
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')
# Теперь нам надо распарсить список групп и найти нужную
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'):
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:
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
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)
# Парсим полученные данные
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, ауд. спортзал*",
# "up_or_down": 'none'
# }
# )
# }
# )
# Верхняя - нечетная неделя
# Нижняя - четная неделя
# Верстка сайта на высоте. Придется использовать 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':
# какая пара
# print(cur_sibl.text)
cur_lesson_time = 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'})
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')
from datetime import date
import locale
locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8")
today_weekday = date.today().strftime('%A')
today_week = date.today().strftime('%U')
print("Сегодня {}, {} ебали на:".format(today_weekday, fucker_name))
for para in rasp_summary:
if para['date'] == today_weekday:
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'])