diff --git a/cloud.py b/cloud.py new file mode 100644 index 0000000..4b680ed --- /dev/null +++ b/cloud.py @@ -0,0 +1,28 @@ +import oss2 +import json +import shutil +import os +import get_answer +#获取本地json文件 +def get_json(file): + return [i for i in os.listdir(file) if i.endswith('.json')] +json_name = get_json(os.getcwd())[0] +# 阿里云 OSS 配置 +access_key_id = 'LTAI5t927vdUFZa9NRnWfrL3' +access_key_secret = 'FbXoJUqe545eZhWFvADvGcFwatsGAx' +bucket_name = 'tasks-jsons' +endpoint = '' +# 创建Bucket对象,所有Object相关的接口都可以通过Bucket对象来进行 +bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name) +# 判断文件是否存在 +exist = bucket.object_exists(json_name) +# 如果文件存在,则下载到本地并覆盖本地文件 +if exist: + bucket.get_object_to_file(json_name, json_name) + print('已从云服务器下载文件') +else: #否则调用OpenAI API获得答案,并上传到云服务器 + new_data = get_answer.new_data + #将new_data变为json格式并上传到云端 + with open(json_name, 'w', encoding='utf-8') as f: + json.dump(new_data, f, ensure_ascii=False, indent=4) + bucket.put_object_to_file(json_name,json_name) diff --git a/get_answer.py b/get_answer.py new file mode 100644 index 0000000..8a1732b --- /dev/null +++ b/get_answer.py @@ -0,0 +1,87 @@ +''' +本模块用于答案获得 +1、先获得本地的json文件 +2、云端检查json是否存在,存在则直接调用,不存在则步骤3 +3、调用openai的api获得答案并处理格式,生成新的json文件并存储在云端 +''' +from openai import AsyncOpenAI +import os +import json +import asyncio +#读取当前目录下的json文件 +#获得指定目录下的所有json文件的文件名 +def get_json(file): + return [i for i in os.listdir(file) if i.endswith('.json')] +#将file指定为当前目录 +file = os.getcwd() +#获得json文件名,因为程序逻辑是每次只有一个json文件,所以直接取第一个 +''' +后续准备与云服务器连接,先判断当前json是否已在云服务器上,如果在,则直接调用, +节省调用API的时间和资费,否则,调用API,获得答案,并将答案存入云服务器 +阿里云服务器申请成功! +''' +json_name = get_json(file)[0] +#读取json文件并转换为字典 +with open(json_name,'r',encoding='utf-8') as f: + data = json.load(f) +#遍历字典,获得每一关的参数,构造请求,获得答案 +''' +用于构造请求的参数:describe,require,code +向GPT提问的格式:promot + 参数模板化的问题 +''' +os.environ['http_proxy'] = 'http://127.0.0.1:10809' +os.environ['https_proxy'] = 'http://127.0.0.1:10809' + +promot = '现在,我想让你扮演一个Python程序员来解一个问题,我的问题将由三个部分组成,第一部分是问题的描述,第二部分是问题的需求,第三部分是问题的代码,我需要你按照我的模板编写代码。并且你返回的代码应当是带有注释的' +#构造问题模板 +#遍历字典,获得每一关的参数,构造请求,获得答案 +#使用异步函数提升效率 +''' +异步思路:由于每一关都会的答案查询都是独立的,可以把不同的查询请求构建成异步任务,谁先完成就先返回谁的答案, +最后把所有的答案整合到一个字典中,再写入json文件中 +''' + +# 初始化异步客户端 +client = AsyncOpenAI( + api_key='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' +) +def get_answer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict: + data = jsonfile + client = client + promot = promot + # 异步函数来获取答案 + async def get_answer(value): + des, req, code = value['describe'], value['require'], value['code'] + question = f'问题描述:{des}\n任务需求:{req}\n根据上面的需求,你需要补充并完善代码:\n{code}' + try: + response = await client.chat.completions.create( + model='gpt-3.5-turbo', + messages=[ + {'role': 'system', 'content': promot}, + {'role': 'user', 'content': question} + ] + ) + return response.choices[0].message.content + except Exception as e: + print(f'错误信息:{e}') + + # 主函数 + async def main(data) -> dict: + tasks = [get_answer(value) for value in list(data.values())[:1:]] + answers = await asyncio.gather(*tasks) + + # 在data的每个value中新增一个键值对,键为answer,值为答案,并作为返回值返回 + for i,val in enumerate(data.values()): + val['answer'] = answers[i] + + return data + + + # 运行主函数 + return asyncio.run(main(data=data)) +new_data = get_answer_from_api(jsonfile=data,client=client,promot=promot) +print(new_data) +#重写本地json文件 +with open(json_name,'w',encoding='utf-8') as f: + json.dump(new_data,f,ensure_ascii=False,indent=4) + diff --git a/get_params.py b/get_params.py index c6d47ce..3d979c1 100644 --- a/get_params.py +++ b/get_params.py @@ -32,12 +32,12 @@ user_name = 'hnu202311020126' password = 'hzy123456' safari = Chrome() safari.get(url) -time.sleep(5) #等待页面加载 +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(4) +time.sleep(2) #获取cookie,User-Agent Cookie = safari.get_cookies() User_Agent = safari.execute_script('return navigator.userAgent') @@ -73,10 +73,11 @@ total = {} i=1 try: while i <= task_num: + safari.implicitly_wait(10) safari.find_element(By.XPATH, '//*[@id="task-left-panel"]/div[1]/a[1]').click() - time.sleep(2) + safari.implicitly_wait(10) safari.find_element(By.XPATH,f'/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[{i}]/div[1]/a').click() - time.sleep(4) + time.sleep(3) #获取课程id -> 根据url中?前面的,最后一个/后面的那部分参数构造请求,同时,似乎还需要用到cookie,User-Agent和Referer参数,这些统一用selenium在登陆后获取并组装成headers #获取cookie,User-Agent和Referer cur_url=Referer = safari.current_url @@ -101,8 +102,7 @@ try: require = obj2.findall(page_source) #获取编辑器中的代码,由于代码都是class = "view-line"的div,先找到所有class = "view-line"的div,获取其中的所有文本,再把不同行的代码用\n连接起来 code = safari.find_elements(By.CLASS_NAME,'view-line') - code = '\n'.join([i.text for i in code]) - + code = '\n'.join([i.text for i in code]).lstrip('\n') #把参数存入字典,再转换为json格式 task = { 'describe':describe[0] if len(describe) != 0 else '', @@ -117,6 +117,5 @@ try: except BaseException: print('获取参数失败') #把参数写入本地json文件中,文件名字与实shixun_name相同键为course_id,值为一个列表,列表中每个元素为一个字典,字典中包含每一关的参数 -#这些数据都是将要上传到云端的,为防止每次运行程序都覆盖了,需要改写写入文件的逻辑 with open(f'{shixun_id}.json','w',encoding='utf-8') as f: json.dump(total,f,ensure_ascii=False,indent=4)