Created
November 14, 2018 22:58
-
-
Save Redict/872a9429c6eff3d450833c8d54fc9b18 to your computer and use it in GitHub Desktop.
MTUCI Testing script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import aiohttp | |
import asyncio | |
from urllib.request import quote as qt | |
from bs4 import BeautifulSoup | |
TESTING_URL = "http://testing.mtuci.ru" | |
TEMPLATE = """ | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" /> | |
<title>Тестирование</title> | |
<link rel="stylesheet" type="text/css" href="http://testing.mtuci.ru/css.css"> | |
</head> | |
{} | |
</html> | |
""" | |
class Test: | |
def __init__(self, name, id_): | |
self.name = name | |
self.id = id_ | |
class MTUCITesting: | |
def __init__(self, identifier): | |
self.authorized = False | |
self.identifier = qt(identifier.encode('cp1251')) | |
self.sess = aiohttp.ClientSession(headers={"Content-Type": "application/x-www-form-urlencoded"}) | |
async def close(self): | |
await self.sess.close() | |
async def _default_cookies(self): | |
async with self.sess.get(f"{TESTING_URL}/index.php"): | |
return | |
async def get_tests(self): | |
async with self.sess.get(f"{TESTING_URL}/list.php") as resp: | |
t = await resp.text() | |
if not t: | |
raise Exception("Unable to get content!") | |
soup = BeautifulSoup(t, 'lxml') | |
tests = list(map(lambda x: Test(x.text, int(x.find('input')['value'])), soup.find_all('h2', onclick=lambda x: x))) | |
if not len(tests): | |
raise Exception("No tests found!") | |
return tests | |
async def render_page(self, test: Test, iterations = 1000): | |
answers = await self.cycle_test(test, iterations) | |
result = "" | |
for answer in answers: | |
result += f"{answer['question']} <b>Answer: </b> {answer['answers'][0]}<p>" | |
return TEMPLATE.format(result) | |
async def cycle_test(self, test: Test, iterations): | |
async def get_question(): | |
async with self.sess.post(f"{TESTING_URL}/test_session.php", | |
data=f"user_test_choice={test.id}") as resp: | |
if resp.status != 200: | |
raise Exception("Unable to start test!") | |
t = await resp.text() | |
if not t: | |
raise Exception("Unable to get content!") | |
soup = BeautifulSoup(t, 'lxml') | |
try: | |
question = soup.find(class_="questionDiv") | |
except: | |
return await get_question() | |
try: | |
answers = list(map(lambda x: x , soup.find(class_="someanswer").find_all("li"))) | |
except: | |
return await get_question() | |
for answer in answers: | |
answer.input.decompose() | |
return {"question": question, "answers": answers} | |
async def find_id(answer): | |
async with self.sess.post(f"{TESTING_URL}/test_session.php", | |
data=f"user_test_choice={test.id}") as resp: | |
if resp.status != 200: | |
raise Exception("Unable to start test!") | |
t = await resp.text() | |
if not t: | |
raise Exception("Unable to get content!") | |
soup = BeautifulSoup(t, 'lxml') | |
answers = list(map(lambda x: [x.input['value'], x] , soup.find(class_="someanswer").find_all("li"))) | |
for answer_ in answers: | |
answer_[1].input.decompose() | |
for an in answers: | |
if an[1] == answer: | |
return an[0] | |
return 0 | |
async def test_result(): | |
async with self.sess.post(f"{TESTING_URL}/test_session.php", data="print=1&rb=%CF%F0%E5%F0%E2%E0%F2%FC&f=0") as resp: | |
t = await resp.text() | |
if not t: | |
raise Exception("Unable to get content!") | |
soup = BeautifulSoup(t, 'lxml') | |
return bool(int(soup.find('td').text)) | |
async def answer_question(id): | |
async with self.sess.post(f"{TESTING_URL}/test_session.php", data=f"answer%5B%5D={id}&print=1&rb=%CE%F2%E2%E5%F2%E8%F2%FC&f=0") as resp: | |
pass | |
async def skip_question(): | |
async with self.sess.post(f"{TESTING_URL}/test_session.php", data="print=1&f=0") as resp: | |
pass | |
try: | |
await test_result() | |
except: | |
pass | |
questions = [] | |
for i in range(iterations): | |
flag = False | |
quest = await get_question() | |
q = list(filter(lambda q: q['question'] == quest['question'], questions)) | |
if len(q): | |
q = q[0] | |
else: | |
questions.append(await get_question()) | |
q = questions[-1] | |
if len(q['answers']) == 1: | |
answer = q['answers'][0] | |
await skip_question() | |
continue | |
else: | |
answer = q['answers'].pop() | |
await answer_question(await find_id(answer)) | |
if await test_result(): | |
q['answers'] = [answer] | |
return questions | |
async def authorize(self): | |
async with self.sess.post(f"{TESTING_URL}/list.php", data=f"p={self.identifier}&h=") as resp: | |
if resp.status != 200: | |
self.close() | |
raise Exception("WARNING! YOU ARE DEBIL!") | |
elif "неправильный идентификатор" in await resp.text(): | |
self.close() | |
raise Exception("Wrong identificator!") | |
else: | |
self.authorized = True | |
async def main(): | |
identifier = input("Введите ваш идентификатор: ") | |
uraj = MTUCITesting(identifier); await uraj.authorize() | |
tests = await uraj.get_tests() | |
print("Доступные тесты:\n", '\n'.join([x.name.strip() for x in tests])) | |
test_you_need = input("Введите название теста(можно не полностью): ") | |
tests = list(filter(lambda x: test_you_need in x.name, tests)) | |
if not len(tests): | |
print("ВНИМАНИЕ!!! ВЫ ДЕБИЛ!!") | |
await uraj.close() | |
exit() | |
iters = input("Введите количество операций: ") | |
if not iters.isdigit(): | |
print("ВНИМАНИЕ!!! ВЫ ДЕБИЛ!!") | |
else: | |
iters = int(iters) | |
from time import time | |
t = time() | |
print(await uraj.render_page(tests[0], iters), file=open(f"{tests[0].name}.html", "wt", encoding='cp1251')) | |
print(f"Время выполнения: {time() - t}") | |
await uraj.close() | |
if __name__ == "__main__": | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment