def login(browser: XuexiChrome): """ 扫码登录流程,将登录的最终结果返回给主程序 :param browser: browser :return: bool,表示是否登录成功 """ browser.xuexi_get('https://pc.xuexi.cn/points/my-points.html') sleep(2.5) print('--> 请在5分钟内扫码完成登录') browser.implicitly_wait(10) qglogin = browser.find_element(by=By.ID, value='qglogin') browser.execute_script('arguments[0].scrollIntoView();', qglogin) for i in range(60): if browser.current_url == 'https://pc.xuexi.cn/points/my-points.html': print('--> 登录成功') return True sleep(5) return False
def run_exam(browser: XuexiChrome): while True: content = browser.find_element(by=By.CLASS_NAME, value='ant-breadcrumb') browser.execute_script('arguments[0].scrollIntoView();', content) sleep(round(uniform(2, 3), 2)) # 题目类型 question_type = browser.find_element(by=By.CLASS_NAME, value='q-header').text # print(questionType) # 当前题目的坐标 question_index = int(browser.find_element(by=By.CLASS_NAME, value='big').text) # 题目总数 question_count = int(findall('/(.*)', browser.find_element(by=By.CLASS_NAME, value='pager').text)[0]) # 确定按钮 ok_btn = browser.find_element(by=By.CLASS_NAME, value='ant-btn-primary') try: browser.find_element(by=By.CLASS_NAME, value='answer') if ok_btn.text == '下一题': ok_btn.click() sleep(round(uniform(0.2, 0.8), 2)) continue except NoSuchElementException: pass # 提示按钮 tip_btn = browser.find_element(by=By.CLASS_NAME, value='tips') print('--> 当前题目进度:' + str(question_index) + '/' + str(question_count)) tip_btn.click() sleep(round(uniform(0.2, 0.8), 2)) try: # 获取所有提示内容 tips_content = browser.find_element(by=By.CLASS_NAME, value='line-feed').find_elements(by=By.TAG_NAME, value='font') sleep(round(uniform(0.2, 0.8), 2)) tip_btn.click() tips = [] tips.clear() for tip in tips_content: tips.append(tip.text) if '单选题' in question_type: # 选择题,获取所有选项 options = browser.find_elements(by=By.CLASS_NAME, value='choosable') if len(tips) == 0: sleep(round(uniform(0.2, 0.8), 2)) options[0].click() else: ans_dict = {} # 存放每个选项与提示的相似度 for i in range(len(options)): ans_dict[i] = SequenceMatcher(None, tips[0], options[i].text[3:]).ratio() ans_dict = sorted(ans_dict.items(), key=lambda x: x[1], reverse=True) # print(ansDict) print('--> 最大概率选项: ' + options[ans_dict[0][0]].text[0]) options[ans_dict[0][0]].click() sleep(round(uniform(0.2, 0.8), 2)) ok_btn.click() elif '多选题' in question_type: # 选择题,获取所有选项 options = browser.find_elements(by=By.CLASS_NAME, value='choosable') q_word = browser.find_element(by=By.CLASS_NAME, value='q-body').text bracket_count = len(findall('()', q_word)) if len(options) == bracket_count: select_all(options) else: if len(tips) == 0: sleep(round(uniform(0.2, 0.8), 2)) options[0].click() sleep(round(uniform(0.2, 0.8), 2)) options[1].click() else: # 如果选项数量多于提示数量,则匹配出最可能的选项 if len(options) > len(tips): ans = [] # 存放匹配出的最终结果 for i in range(len(tips)): ans_dict = {} # 存放每个选项与提示的相似度 for j in range(len(options)): ans_dict[j] = SequenceMatcher(None, tips[i], options[j].text[3:]).ratio() # print(ansDict) ans_dict = sorted(ans_dict.items(), key=lambda x: x[1], reverse=True) ans.append(ans_dict[0][0]) ans = list(set(ans)) # print(ans) print('--> 最大概率选项:', end='') for i in range(len(ans)): print(' ' + options[ans[i]].text[0], end='') print() for i in range(len(ans)): sleep(round(uniform(0.2, 0.8), 2)) options[ans[i]].click() # 如果选项数量和提示数量相同或少于提示数量,则全选 else: select_all(options) sleep(round(uniform(0.2, 0.8), 2)) ok_btn.click() elif '填空题' in question_type: # 填空题,获取所有输入框 blanks = browser.find_elements(by=By.CLASS_NAME, value='blank') tips_i = 0 for i in range(len(blanks)): sleep(round(uniform(0.2, 0.8), 2)) if len(tips) > tips_i and tips[tips_i].strip() == '': tips_i += 1 try: blank_ans = tips[tips_i] except: blank_ans = '未找到提示' print('--> 第{0}空答案可能是: {1}'.format(i + 1, blank_ans)) blanks[i].send_keys(blank_ans) tips_i += 1 sleep(round(uniform(0.2, 0.8), 2)) ok_btn.click() except UnexpectedAlertPresentException: alert = browser.switch_to.alert alert.accept() other_place = browser.find_element(by=By.ID, value='app') other_place.click() sleep(round(uniform(0.2, 0.8), 2)) except WebDriverException: print(str(format_exc())) print('--> 答题异常,正在重试') other_place = browser.find_element(by=By.ID, value='app') other_place.click() sleep(round(uniform(0.2, 0.8), 2)) if question_index == question_count: sleep(round(uniform(0.2, 0.8), 2)) try: submit = browser.find_element(by=By.CLASS_NAME, value='submit-btn') submit.click() browser.implicitly_wait(10) sleep(round(uniform(2.6, 4.6), 2)) except NoSuchElementException: submit = browser.find_element(by=By.CLASS_NAME, value='ant-btn-primary') submit.click() browser.implicitly_wait(10) sleep(round(uniform(2.6, 4.6), 2)) except UnexpectedAlertPresentException: alert = browser.switch_to.alert alert.accept() print('--> 答题结束') break