Skip to content

Instantly share code, notes, and snippets.

@Redict
Created November 14, 2018 22:58
Show Gist options
  • Save Redict/872a9429c6eff3d450833c8d54fc9b18 to your computer and use it in GitHub Desktop.
Save Redict/872a9429c6eff3d450833c8d54fc9b18 to your computer and use it in GitHub Desktop.
MTUCI Testing script
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