From 5c2b3fa7e01265fbbcdb307e325da87be70d3c1f Mon Sep 17 00:00:00 2001 From: JesterHey <144512889+JesterHey@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:53:41 +0800 Subject: [PATCH] Add files via upload --- apis.json | 1 + demo.py | 11 +- demo2.py | 11 ++ get_answer.py | 9 +- get_params.py | 380 ++++++++++++++++++++++-------------------- main.py | 4 +- printtxt.py | 2 +- tempCodeRunnerFile.py | 21 +++ trans_to_txt.py | 5 +- 9 files changed, 243 insertions(+), 201 deletions(-) create mode 100644 apis.json create mode 100644 demo2.py create mode 100644 tempCodeRunnerFile.py diff --git a/apis.json b/apis.json new file mode 100644 index 0000000..29c9f7a --- /dev/null +++ b/apis.json @@ -0,0 +1 @@ +{"my_api":"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"} \ No newline at end of file diff --git a/demo.py b/demo.py index 162fa19..caabd78 100644 --- a/demo.py +++ b/demo.py @@ -1,5 +1,6 @@ -import os -def getalljsons() -> list: - return [i for i in os.listdir() if i.endswith('.json')] -for i in getalljsons(): - os.remove(i) \ No newline at end of file +import numpy as np +import pandas as pd +np.random.seed(0) +df1 = pd.DataFrame(np.random.randint(0,10,size=(5, 6)), columns=list('ABCDEF')) +print(df1) +print(df1.head(2)[['A','B']]) \ No newline at end of file diff --git a/demo2.py b/demo2.py new file mode 100644 index 0000000..7c90572 --- /dev/null +++ b/demo2.py @@ -0,0 +1,11 @@ +import requests +headers = { + 'Cookie': 'autologin_trustie=bb3a180a619e2e75610e06dcb8181f1951692d36; _educoder_session=497c9154b70e3a840e04f3fba8096472', + 'User-Agent': +'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Referer': 'https://www.educoder.net/tasks/27V4D95N/1191512/8p2s3yzoxuit?coursesId=27V4D95N' +} +url = 'https://data.educoder.net/api/myshixuns/gorxjivf6b/challenges.json' +response = requests.get(url=url,headers=headers) +print(len(response.json())) +response.close() \ No newline at end of file diff --git a/get_answer.py b/get_answer.py index 0e05f50..a587edd 100644 --- a/get_answer.py +++ b/get_answer.py @@ -101,7 +101,7 @@ def get_shixunanswer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> di else: language = get_shixunjson(os.getcwd())[0].split('.')[0].split('_')[-1] data = jsonfile - promot1 = f'现在,我想让你扮演一个资深而经验丰富的程序员来解一个问题,我的问题将由三个部分组成,第一部分是问题的描述,第二部分是问题的需求,第三部分是问题的代码,我需要你按照我的模板编写代码,使用的代码语言是{language}。并且你返回的代码应当是带有注释的。再次注意,请返回完整的,格式正确的,可读的代码!' + promot1 = f'现在,我想让你扮演一个资深而经验丰富的程序员来解一个问题,我的问题将由三个部分组成,第一部分是问题的描述,第二部分是问题的需求,第三部分是问题的代码,我需要你按照我的模板编写代码,使用的代码语言是{language}。并且你返回的代码应当是带有注释的。再次注意,请返回完整的,格式正确的,可读的代码!并且,在没有特殊要求的情况下,不用给出用于运行补全后代码的示例代码' # 异步函数来获取答案 async def get_answer(key,value) -> str: ''' @@ -157,7 +157,7 @@ def get_programming_answer_from_api(jsonfile:list,client:AsyncOpenAI,promot:str) else: language = get_shixunjson(os.getcwd())[0].split('.')[0].split('_')[-1] data = jsonfile - promot2 = f'现在,我想让你扮演一个资深而经验丰富的程序员来解一个问题,我的问题会有两个部分组成,第一部分是问题的描述,第二部分是你需要补全或者完善的代码。你需要阅读,理解我的问题描述,然后补全或者完善代码,使用的代码语言是{language}。再次注意,请返回完整的,格式正确的,输入由用户给出的,可读的代码!' + promot2 = f'现在,我想让你扮演一个资深而经验丰富的程序员来解一个问题,我的问题会有两个部分组成,第一部分是问题的描述,第二部分是你需要补全或者完善的代码。你需要阅读,理解我的问题描述,然后补全或者完善代码,使用的代码语言是{language}。再次注意,请返回完整的,格式正确的,输入由用户给出的,可读的代码!并且,在没有特殊要求的情况下,不用给出用于运行补全后代码的示例代码' # 异步函数来获取答案 async def get_answer(value:dict) -> str: pro_id = value['id'] @@ -205,8 +205,7 @@ def get_programming_answer_from_api(jsonfile:list,client:AsyncOpenAI,promot:str) if __name__ == '__main__': promot='' - ans = get_programming_answer_from_api(jsonfile=get_programmingjson(os.getcwd()),client=client,promot=promot) + ans = get_shixunanswer_from_api(load_json_data(get_shixunjson(os.getcwd())[0]),client=client,promot=promot) print(ans) - rewrite_programming_json(json_names=get_programmingjson(os.getcwd()), - new_data=ans) + rewrite_shixun_json(get_shixunjson(os.getcwd())[0],ans) #new_data = get_programming_answer_from_api(get_programmingjson(os.getcwd()),client=client,promot=promot2) diff --git a/get_params.py b/get_params.py index 0679f56..62c7033 100644 --- a/get_params.py +++ b/get_params.py @@ -8,12 +8,11 @@ 3、课程id,实训id 4、写入本地json文件中 ''' - +globals()['retry'] = 0 #导入所需模块 import platform import os import json -import time from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By @@ -23,12 +22,10 @@ from lxml import etree import time import requests from cloud import is_exist,download -global retry -retry = 0 #配置参数 opt = Options() opt.add_experimental_option('detach', True) -opt.add_argument('--headless') +#opt.add_argument('--headless') platf = platform.platform() def is_practice(url:str) -> bool: obj=re.compile(r'www.educoder.net/tasks') @@ -45,188 +42,201 @@ def is_programming(url:str) -> bool: # 另外,目前好像只有实训作业有这些参数,其他的作业例如编程作业就没有,所以先判断一下是否为实训作业,可以通过用户输入的url判断 # 主要是看educoder.net/后面是否有tasks,如果有,则是实训作业,否则,不是实训作业 #为方便main.py调用,将判断函数写入函数中,以下部分封装为函数 -def get_parameters(url: str, user_name: str, password: str): +def get_parameters(url: str, user_name: str, password: str,retry:int=2): ''' 用于获得实训作业的参数 url:实训网址 user_name:用户名 password:密码 ''' - url = url - user_name = user_name - password = password - if is_practice(url): - #构造selenium对象 - safari = Chrome(options=opt) - safari.get(url) - #模拟登录 - safari.implicitly_wait(10) - safari.find_element(By.ID, 'login').send_keys(user_name) - safari.find_element(By.ID, 'password').send_keys(password) - safari.find_element(By.ID, 'password').send_keys(Keys.ENTER) - time.sleep(2) - #判断是否登录成功 - try: - safari.find_element(By.XPATH, - '//*[@id="task-left-panel"]/div[1]/a[1]') - except BaseException: - print('登录失败 请检查输入信息是否正确') - # 关闭浏览器 - safari.quit() - # #重新调用login_ui.py - # if 'Windows' in platf: - # os.system('python login_ui.py') - # else: - # os.system('python3 login_ui.py') - #获取cookie,User-Agent - Cookie = safari.get_cookies() - User_Agent = safari.execute_script('return navigator.userAgent') - cookie = f'autologin_trustie={Cookie[1]["value"]}; _educoder_session={Cookie[0]["value"]}' - #先获取到shixun_id便于先判断云端文件是否存在 - cur_url = url - identity = cur_url.split('/')[-1].split('?')[0] - id_url = f'https://data.educoder.net/api/tasks/{identity}.json?' - headers = { - 'Cookie': cookie, - 'User-Agent': User_Agent, - 'Referer': cur_url - } - response = requests.get(url=id_url, headers=headers) - shixun_id = dict(response.json())['challenge']['shixun_id'] - language = requests.get(f'https://data.educoder.net/api/tasks/{identity}/rep_content.json',headers=headers).json()['content']['language'] - #判断云端文件是否存在 - exist = is_exist(f'{shixun_id}_{language}.json') - if exist: - try: - print('云端文件已存在,正在下载') - download(f'{shixun_id}.json') - # 检测本地文件是否下载完成 - while True: - try: - if os.path.exists(f'{shixun_id}_{language}.json'): - print('下载完成') - safari.quit() - return - break - except Exception as e: - print(e) - except Exception as e: - print(e) - else: #不存在,则继续执行本程序 - print('云端文件不存在,正在爬取') - #获取关卡数 - #点击展开关卡页面 - time.sleep(3) - safari.find_element( - By.XPATH, '//*[@id="task-left-panel"]/div[1]/a[1]').click() - #关卡数量由 class = "flex-container challenge-title space-between" 的元素数量决定 - time.sleep(3) - htmltxt = safari.page_source - html = etree.HTML(htmltxt) - task_num = html.xpath( - 'count(//*[@class="flex-container challenge-title space-between"])' - ) - task_num = int(task_num) - print(f'关卡数量为{task_num}') - #回到第一关 - time.sleep(3) - safari.find_element( - By.XPATH, - '//*[@id="task-left-panel"]/div[3]/div[3]/div/div/div/div/div[1]/div[1]/a' - ).click() - #对于每一关,获取参数 - #每一关的参数由以下元素组成: - ''' - /html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[3]/div[1]/a - /html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[4]/div[1]/a - ''' - obj1 = re.compile( - r'

任务描述

(?P.*?)

', re.S) - obj2 = re.compile( - r'

编程要求

(?P.*?)

', re.S) - #初始化一个字典,用于存放所有关卡的参数 - total = {} - i = 1 + global challenge_id + while retry <= 2: + print('正在获取参数') + url = url + user_name = user_name + password = password + if is_practice(url): + #构造selenium对象 + safari = Chrome(options=opt) + safari.get(url) + #模拟登录 + safari.implicitly_wait(10) + safari.find_element(By.ID, 'login').send_keys(user_name) + safari.find_element(By.ID, 'password').send_keys(password) + safari.find_element(By.ID, 'password').send_keys(Keys.ENTER) + time.sleep(2) + #判断是否登录成功 try: - while i <= task_num: - cur_url = Referer = safari.current_url - identity = cur_url.split('/')[-1].split('?')[0] - id_url = f'https://data.educoder.net/api/tasks/{identity}.json?' - #获取课程id - headers = { - 'Cookie': cookie, - 'User-Agent': User_Agent, - 'Referer': Referer - } - try: + safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[1]/a[1]') + except BaseException: + print('登录失败 请检查输入信息是否正确') + # 关闭浏览器 + safari.quit() + # #重新调用login_ui.py + # if 'Windows' in platf: + # os.system('python login_ui.py') + # else: + # os.system('python3 login_ui.py') + #获取cookie,User-Agent + time.sleep(1) + Cookie = safari.get_cookies() + User_Agent = safari.execute_script('return navigator.userAgent') + cookie = f'autologin_trustie={Cookie[1]["value"]}; _educoder_session={Cookie[0]["value"]}' + #先获取到shixun_id便于先判断云端文件是否存在 + cur_url = safari.current_url + identity = cur_url.split('/')[-1].split('?')[0] + print(identity) + id_url = f'https://data.educoder.net/api/tasks/{identity}.json?' + headers = { + 'Cookie': cookie, + 'User-Agent': User_Agent, + 'Referer': cur_url + } + response = requests.get(url=id_url, headers=headers) + shixun_id = dict(response.json())['challenge']['shixun_id'] + language = requests.get(f'https://data.educoder.net/api/tasks/{identity}/rep_content.json',headers=headers).json()['language'] + identifier = response.json()['myshixun']['identifier'] + print(identifier) + response.close() + #判断云端文件是否存在 + exist = is_exist(f'{shixun_id}_{language}.json') + if exist: + try: + print('云端文件已存在,正在下载') + download(f'{shixun_id}.json') + # 检测本地文件是否下载完成 + while True: + try: + if os.path.exists(f'{shixun_id}_{language}.json'): + print('下载完成') + safari.quit() + return + break + except Exception as e: + print(e) + except Exception as e: + print(e) + else: #不存在,则继续执行本程序 + print('云端文件不存在,正在爬取') + #获取关卡数 + #点击展开关卡页面 + time.sleep(2) + safari.find_element( + By.XPATH, '//*[@id="task-left-panel"]/div[1]/a[1]').click() + # 展开后,服务器会返回一个challenges.json文件,里面包含了所有关卡的参数 + # https://data.educoder.net/api/myshixuns/{identifier}/challenges.json 这个链接就是返回的json文件 + identifier_url = f'https://data.educoder.net/api/myshixuns/{identifier}/challenges.json' + resp2 = requests.get(url=identifier_url, headers=headers) + #获取关卡数量 + print(resp2.json()) + task_num = len(resp2.json()) + resp2.close() + #回到第一关 + time.sleep(2) + safari.find_element( + By.XPATH, + '//*[@id="task-left-panel"]/div[3]/div[3]/div/div/div/div/div[1]/div[1]/a' + ).click() + #对于每一关,获取参数 + #每一关的参数由以下元素组成: + ''' + /html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[3]/div[1]/a + /html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[4]/div[1]/a + ''' + obj1 = re.compile( + r'

任务描述

(?P.*?)

', re.S) + obj2 = re.compile( + r'

编程要求

(?P.*?)

', re.S) + #初始化一个字典,用于存放所有关卡的参数 + total = {} + i = 1 + try: + while i <= task_num: + time.sleep(2) + cur_url = Referer = safari.current_url + identity = cur_url.split('/')[-1].split('?')[0] + id_url = f'https://data.educoder.net/api/tasks/{identity}.json?' + #获取课程id + headers = { + 'Cookie': cookie, + 'User-Agent': User_Agent, + 'Referer': Referer + } response = requests.get(url=id_url, headers=headers) - challenge_id = dict(response.json())['challenge']['id'] - shixun_id = dict(response.json())['challenge']['shixun_id'] - except BaseException: - print('获取课程id失败') - #获取任务描述(如果存在的话) - time.sleep(3) - page_source = safari.page_source - describe = obj1.findall(page_source) - #获取编程要求(如果存在的话) - require = obj2.findall(page_source) - #获取编辑器中的代码,采用requests抓取https://data.educoder.net/api/tasks/{identity}/rep_content.json中的content中的content - # 然后然后,这个content是一个base64编码的字符串,需要解码 - code = requests.get( - f'https://data.educoder.net/api/tasks/{identity}/rep_content.json', - headers=headers).json()['content']['content'] - #把参数存入字典,再转换为json格式 - task = { - 'describe': - describe[0] if len(describe) != 0 else '', - 'require': - require[0] if len(require) != 0 else '', - 'code': - code, - 'verified': - False, #这个参数是用来标记答案是否被用户认证为正确答案的,初始值为False - 'last_modified': - time.strftime( - '%Y-%m-%d %H:%M:%S', time.localtime( - time.time())), #这个参数是用来标记答案最后一次被修改的时间,初始值为当前时间 - 'language': - language if language != None else '' - } - #把每一关的参数存入总的字典中 - total[challenge_id] = task - #去往下一关 - safari.implicitly_wait(10) - if i == 1: - i += 1 - safari.find_element(By.XPATH,f'//*[@id="task-right-panel"]/div[4]/div/div[2]/a').click() - elif i < task_num: - i += 1 - safari.find_element(By.XPATH,f'//*[@id="task-right-panel"]/div[4]/div/div[2]/a[2]').click() - else: - i += 1 - except Exception as e: - print(e) - print(f'{i}关参数获取参数失败') - #判断爬取到的代码是否存在空值或者键的数量是否与关卡数量相等,如果不相等,则说明爬取失败,需要重新爬取 - - # if len(total) != task_num: - # print('参数爬取失败,正在重新爬取') - # get_parameters(url,user_name,password) - # else: - # for i,j in total.items(): - # if j['code'] == '': - # print('参数爬取失败,正在重新爬取') - # get_parameters(url,user_name,password) - - #把参数写入本地json文件中,文件名字与shixun_name相同键为course_id,值为一个列表,列表中每个元素为一个字典,字典中包含每一关的参数 - with open(f'{shixun_id}_{language}.json', 'w', encoding='utf-8') as f: - json.dump(total, f, ensure_ascii=False, indent=4) - print('参数爬取完成') - #关闭浏览器 - safari.quit() - else: - print('这不是一个实训作业') - return + challenge_id = response.json()['challenge']['id'] + shixun_id = response.json()['challenge']['shixun_id'] + print(f'第{i}关的id为{challenge_id},爬取成功') + #获取任务描述(如果存在的话) + time.sleep(2) + page_source = safari.page_source + describe = obj1.findall(page_source) + #获取编程要求(如果存在的话) + require = obj2.findall(page_source) + #获取编辑器中的代码,采用requests抓取https://data.educoder.net/api/tasks/{identity}/rep_content.json中的content中的content + # 然后然后,这个content是一个base64编码的字符串,需要解码 + code = requests.get( + f'https://data.educoder.net/api/tasks/{identity}/rep_content.json', + headers=headers).json()['content']['content'] + #把参数存入字典,再转换为json格式 + task = { + 'describe': + describe[0] if len(describe) != 0 else '', + 'require': + require[0] if len(require) != 0 else '', + 'code': + code, + 'verified': + False, #这个参数是用来标记答案是否被用户认证为正确答案的,初始值为False + 'last_modified': + time.strftime( + '%Y-%m-%d %H:%M:%S', time.localtime( + time.time())), #这个参数是用来标记答案最后一次被修改的时间,初始值为当前时间 + 'language': + language if language != None else '' + } + print(f'第{i}关的参数为{task}') + #把每一关的参数存入总的字典中 + total[challenge_id] = task + print('当前参数为') + print(total) + #去往下一关 + safari.implicitly_wait(10) + if i <= 1: + i += 1 + safari.find_element(By.XPATH,f'//*[@id="task-right-panel"]/div[4]/div/div[2]/a').click() + elif i < task_num: + i += 1 + safari.find_element(By.XPATH,f'//*[@id="task-right-panel"]/div[4]/div/div[2]/a[2]').click() + else: + i += 1 + except Exception as e: + print(e) + print(f'{i}关参数获取参数失败') + #判断爬取到的代码是否存在空值或者键的数量是否与关卡数量相等,如果不相等,则说明爬取失败,需要重新爬取 + if len(total) != task_num: + if retry <= 2: + print('参数有数量不对等,正在重新爬取') + retry -= 1 + continue + else : + print('参数爬取失败,超过最大重试次数,爬取失败') + return + elif len(total) == task_num: + for i,j in total.items(): + if j['code'] == '' and retry <= 2: + print('参数有空值,正在重新爬取') + retry -= 1 + continue + #把参数写入本地json文件中,文件名字与shixun_name相同键为course_id,值为一个列表,列表中每个元素为一个字典,字典中包含每一关的参数 + with open(f'{shixun_id}_{language}.json', 'w', encoding='utf-8') as f: + json.dump(total, f, ensure_ascii=False, indent=4) + print('参数爬取完成') + #关闭浏览器 + safari.quit() + return + else: + print('这不是一个实训作业') + return def get_parameters_of_programming(url:str,user_name:str,password:str): ''' @@ -235,6 +245,7 @@ def get_parameters_of_programming(url:str,user_name:str,password:str): user_name:用户名 password:密码 ''' + print('正在获取参数') url = url user_name = user_name password = password @@ -266,7 +277,7 @@ def get_parameters_of_programming(url:str,user_name:str,password:str): Cookie = safari.get_cookies() User_Agent = safari.execute_script('return navigator.userAgent') cookie = f'autologin_trustie={Cookie[1]["value"]}; _educoder_session={Cookie[0]["value"]}' - heders = { + headers = { 'Cookie':cookie, 'User-Agent':User_Agent, 'Referer':url @@ -297,13 +308,12 @@ def get_parameters_of_programming(url:str,user_name:str,password:str): i = 1 while i<=task_num: # 对于每一关,获取参数 + time.sleep(1) cur_url = safari.current_url identity = cur_url.split('/')[-1].split('?')[0] - resp = requests.get(f'https://data.educoder.net/api/myproblems/{identity}.json',headers=heders) + resp = requests.get(f'https://data.educoder.net/api/myproblems/{identity}.json',headers=headers) # 提取resp中的题目id,题干,代码等参数 problem_data = resp.json() - # 初始化一个字典,用于存放所有关卡的参数 - total = {} # 题目id pro_id = problem_data['hack']['id'] language = problem_data['hack']['language'] @@ -345,8 +355,8 @@ def get_parameters_of_programming(url:str,user_name:str,password:str): print('不是编程作业') if __name__ == '__main__': - url = 'https://www.educoder.net/myproblems/9kwnlzvcegsa?type=1' + url = 'https://www.educoder.net/tasks/27V4D95N/1363622/bkxl9wqvfjos?coursesId=27V4D95N' user_name = 'hnu202311020126' password = 'hzy123456' - get_parameters_of_programming(url,user_name,password) + get_parameters(url,user_name,password) print('结束测试') diff --git a/main.py b/main.py index 03b11a1..14880e0 100644 --- a/main.py +++ b/main.py @@ -21,8 +21,6 @@ from trans_to_txt import transToTxt,transToTxt_programming,get_programmingjson,g import json import os from printtxt import print_txt,get_all_txt_file -global finished -finished = False # 调用login_ui获得用户输入的用户名、密码和实训网址 show_image() show_login() @@ -40,7 +38,7 @@ url = userinfo['url'] ispractice = is_practice(url=url) if ispractice: # 调用get_params.py获得参数,完成后本地应该有一个json文件,里面有参数 - get_parameters(url,user_name,password) + get_parameters(url=url,user_name=user_name,password=password) else: get_parameters_of_programming(url=url,user_name=user_name,password=password) print('参数获取完成!') diff --git a/printtxt.py b/printtxt.py index 2e2fd76..a4f789b 100644 --- a/printtxt.py +++ b/printtxt.py @@ -50,7 +50,7 @@ class TypewriterEffectApp(QWidget): self.index = 0 self.timer = QTimer(self) self.timer.timeout.connect(self.displayNextCharacter) - self.timer.start(20) + self.timer.start(5) def displayNextCharacter(self): if self.index < len(self.content): diff --git a/tempCodeRunnerFile.py b/tempCodeRunnerFile.py new file mode 100644 index 0000000..32724c3 --- /dev/null +++ b/tempCodeRunnerFile.py @@ -0,0 +1,21 @@ +class Solution: + def maxArea(self, height) -> int: + # 设x,y是某两根柱子的索引 + # 要找的是表达式 abs(x-y) * min(height[x],height[y]) 之最大值 + # 初始化两个指针,分别指向数组头和尾的索引 + # 若向内移动长板,min()函数的值不变或变小,s必然变小 + # 若向内移动短板,min()函数的值可能变大,s可能变大 + i,j = 0,len(height) - 1 + cur_max = (j-i) * min(height[i],height[j]) + while i cur_max: + cur_max = cur_v + else: + pass + if height[i] <= height[j]: + i += 1 + else: + j -= 1 + return cur_max \ No newline at end of file diff --git a/trans_to_txt.py b/trans_to_txt.py index 03c1f1c..9db1ec3 100644 --- a/trans_to_txt.py +++ b/trans_to_txt.py @@ -47,5 +47,6 @@ if __name__ == '__main__': print('测试部分') # jsons = get_shixunjson(os.getcwd()) # transToTxt(jsons) - jsons = get_programmingjson(os.getcwd()) - transToTxt_programming(jsons=jsons) + jsons = get_shixunjson(os.getcwd()) + print(jsons) + transToTxt(jsons)