1 from selenium import webdriver 2 from time import sleep 3 from bs4 import BeautifulSoup 4 import re 5 from pyperclip import copy, paste 6 import win32api 7 import win32con 8 from jpype import * 9 import urllib.parse 10 import http.client 11 import requests 12 from urllib import request 13 14 15 class Tools: 16 @staticmethod 17 def ctrl_c(): 18 win32api.keybd_event(17, 0, 0, 0) 19 win32api.keybd_event(67, 0, 0, 0) 20 win32api.keybd_event(67, 0, win32con.KEYEVENTF_KEYUP, 0) 21 win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) 22 23 @staticmethod 24 def ctrl_v(): 25 win32api.keybd_event(17, 0, 0, 0) 26 win32api.keybd_event(86, 0, 0, 0) 27 win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) 28 win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) 29 30 @staticmethod 31 def click(): 32 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0) 33 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0) 34 35 # 处理从微信获取的答案 36 @staticmethod 37 def handel_answer(question): 38 answers = re.findall(pattern=re.compile('➖➖➖➖➖➖➖➖➖➖([\s\S]*)➖➖➖➖➖➖➖➖➖➖'), string=paste()) 39 question = question.replace('(', '').replace(')', '').replace('。', '') 40 answers = answers[0].replace('\ue020', '').replace('\n', ''). \ 41 replace('(', '').replace('。', '').replace(')', '').split(question) 42 num = 0 43 for i in range(answers.__len__()): 44 if answers[num] == '' or answers[num].encode('UTF-8').isalpha(): 45 answers.remove(answers[num]) 46 else: 47 answers[num].replace(' ', '') 48 num += 1 49 return answers 50 51 # 发送信息,通知来确认答题 52 @staticmethod 53 def send_sms(): 54 params = urllib.parse.urlencode( 55 {'account': "", 'password': "", 56 'content': '您的验证码是:911。请不要把验证码泄露给其他人。', 57 'mobile': "", 'format': 'json'}) 58 headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} 59 conn = http.client.HTTPConnection("106.ihuyi.com", port=80, timeout=30) 60 conn.request("POST", "/webservice/sms.php?method=Submit", params, headers) 61 response = conn.getresponse() 62 response_str = response.read() 63 conn.close() 64 return response_str 65 66 # 获取视频播放时弹出的答案和弹出时间 67 @staticmethod 68 def get_answer_and_wait_time(source_code, headers, type): 69 knowledgeid = re.findall(pattern=re.compile('knowledgeid=(.*)&num'), string=source_code)[0] 70 if type == 1: 71 return knowledgeid 72 courseid = re.findall(pattern=re.compile('courseId=(.*)&classId'), string=source_code)[0] 73 mdiea_id = requests.get('https://mooc1-2.chaoxing.''com/knowledge/' 74 'cards?''courseid=' + str(courseid) + '&knowledgeid=' + 75 str(knowledgeid) + '', headers=headers).content.decode('utf8') 76 midea_id = re.findall(pattern=re.compile('mid":"(.*)","_jobid'), 77 string=mdiea_id) 78 answer = re.findall( 79 pattern=re.compile('"isRight":true,"name":"(.*)","description".*?"startTime":(.*),"endTime":0'), 80 string=requests.get( 81 'https://mooc1-2.chaoxing.com/richvideo/initdatawithviewer?&start=undefined&mid=' + 82 midea_id[0] + '', 83 headers=headers).text) 84 return answer 85 86 # 获取章节测验的网页source_code 87 @staticmethod 88 def get_questions_page_source(url, headers, knowledgeid, type, browser): 89 ids = re.findall(pattern=re.compile('courseId=(.*)&clazzid=(.*)&enc'), string=url)[0] 90 url = 'https://mooc1-2.chaoxing.com/knowledge/cards?clazzid=' + ids[1] + '&courseid=' + ids[ 91 0] + '&knowledgeid=' + str(knowledgeid) + '&num=' + str(type) + '' 92 temp = requests.get(url=url, headers=headers).text 93 ids_2 = re.findall(pattern=re.compile('jobid":"(.*?)"[\s\S]*"workid":"(.*?)"[\s\S]*enc":"(.*?)"'), string=temp) 94 ids_2 = ids_2[0] 95 url_timu = 'https://mooc1-2.chaoxing.com/api/work?api=1&workId=' + ids_2[1] + '&jobid=' + ids_2[ 96 0] + '&needRedirect=true&knowledgeid=' + knowledgeid + '&courseid=' + ids[0] + '&ut=s&clazzId=' + str( 97 ids[1]) + '&enc=' + str(ids_2[2]) 98 browser.get(url_timu) 99 req = request.Request(url=url_timu, headers=headers) 100 return request.urlopen(req).read().decode('utf8') 101 102 # 处理获取到的问题选项 103 @staticmethod 104 def handle_options(options): 105 options = options.replace('\r', '').replace('\t', '').replace(' ', '').replace('\xa0', '') 106 options = options.split('\n') 107 num = 0 108 for i in range(options.__len__()): 109 if options[num] == '' or options[num].encode('UTF-8').isalpha(): 110 options.remove(options[num]) 111 else: 112 num += 1 113 return options 114 115 def get_answer_from_weichat(self, path, src, question): 116 copy(question) 117 src.click(path + "Input_box.png") 118 self.ctrl_v() 119 src.click(path + "Send.png") 120 sleep(2) 121 src.doubleClick(path + "Answer.png") 122 self.ctrl_c() 123 sleep(2) 124 125 126 class AutoErya: 127 def __init__(self): 128 self.current_url = '' 129 self.question_dict = {'A': '1', 130 'B': '2', 131 'C': '3', 132 'D': '4', 133 '是': '1', 134 '否': '2'} 135 self.tool = Tools() 136 startJVM(get_default_jvm_path(), '-ea', r'-Djava.class.path=C:\Program Files (x86)\Sikuli X\sikuli-script.jar') 137 screen = JClass('org.sikuli.script.Screen') 138 self.src = screen() 139 # sikuli图片地址 140 self.path = "C:\\Users\INnoVation\\test.sikuli\\" 141 self.headers = { 142 'User-Agent': 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) ' 143 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 ' 144 'Safari/537.36', 145 'Cookie': '' 146 } 147 148 # 处理答题 149 def auto_answer(self, browser, knowledgeid, type): 150 sleep(2) 151 questions_source = self.tool.get_questions_page_source(browser.current_url, self.headers, knowledgeid, type, 152 browser) 153 page_source = BeautifulSoup(questions_source, 'lxml') 154 questions = page_source.find_all('div', class_='Zy_TItle clearfix') 155 options = page_source.find_all('ul', class_='Zy_ulTop') 156 First = 1 157 num = 0 158 base_xpath = '//*[@id="ZyBottom"]/div' 159 # 对每一道问题进行处理 160 for question in questions: 161 question = question.text 162 question = question.replace('\n', '') 163 question_type = 1 if re.findall(re.compile('单选题(.*)'), string=question).__len__() > 0 else 2 164 question = question[6:] 165 if question_type == 1: 166 options_ = self.tool.handle_options(options[num].text) 167 num += 1 168 if First > 0: 169 First -= 1 170 else: 171 base_xpath += '/div[3]' 172 choice_xpath = base_xpath + '/div[2]/ul' if question_type == 1 else base_xpath + '/div[2]/div/ul' 173 self.tool.get_answer_from_weichat(src=self.src, question=question, path=self.path) 174 answers = self.tool.handel_answer(question) 175 if question_type == 1: 176 for answer in answers: 177 if answer.encode('UTF-8').isalpha(): 178 browser.find_element_by_xpath( 179 choice_xpath + '/li[' + self.question_dict[str(answer)] 180 + ']/label/input').click() 181 break 182 else: 183 i = 1 184 for option_ in options_: 185 if option_ == answer: 186 browser.find_element_by_xpath( 187 choice_xpath + '/li[' + str(i) 188 + ']/label/input').click() 189 i += 1 190 break 191 else: 192 for answer in answers: 193 if answer == '是': 194 browser.find_element_by_xpath( 195 choice_xpath + '/li[1]/label/input').click() 196 else: 197 browser.find_element_by_xpath( 198 choice_xpath + '/li[2]/label/input').click() 199 self.tool.send_sms() 200 input('请检查答案正确性,确认后提交答案然后请输入Y解除停滞状态') 201 browser.get(self.current_url) 202 sleep(5) 203 204 # 处理视频播放和中途弹出问题 205 def video_play(self, browser, knowledgeid): 206 sleep(3) 207 type = 2 208 # 有学习目标时type为3,反之为2(记录章节测验所在xpath) 209 if browser.find_element_by_xpath('//*[@id="dct2"]').text != '2 章节测验': 210 type = 3 211 browser.find_element_by_xpath('//*[@id="dct2"]').click() 212 if self.src.exists(self.path + 'Finish.png'): 213 browser.find_element_by_xpath('//*[@id="dct' + str(type) + '"]').click() 214 self.auto_answer(browser, knowledgeid, type - 1) 215 sleep(5) 216 self.src.click(self.path + 'Play_video.png') 217 answer = self.tool.get_answer_and_wait_time(browser.execute_script("return document.documentElement.outerHTML"), 218 self.headers, 0)[0] 219 print('开始睡觉,' + answer[1] + 'S后,答题,答案是' + str(answer[0][0]) + '') 220 sleep(int(answer[1]) + 30) 221 self.src.click(self.path + str(answer[0][0] + '.png')) 222 self.src.click(self.path + 'Confirm_Video.png') 223 sleep(2) 224 self.tool.click() 225 # 等待视频已完成图标出现 226 self.src.wait(self.path + 'Finish.png', 6000) 227 browser.find_element_by_xpath('//*[@id="dct' + str(type) + '"]').click() 228 self.auto_answer(browser, knowledgeid, type - 1) 229 230 # 处理视频播放 231 def video_index(self, browser): 232 sleep(3) 233 source_code = BeautifulSoup(browser.execute_script("return document.documentElement.outerHTML"), 'lxml') 234 items = source_code.find_all('div', class_="ncells") 235 i = 0 236 wait_play = [] 237 for item in items: 238 item = str(item) 239 if i == 0: 240 if re.findall(pattern=re.compile('<span class=(.*?)orange01'), string=item) is not None: 241 i = 1 242 continue 243 if i == 1: 244 id = re.findall(pattern=re.compile('<h4.*id="(.*)" style'), string=item) 245 wait_play.append(id[0]) 246 if i == 1: 247 for item in wait_play: 248 browser.find_element_by_xpath('//*[@id="' + item + '"]').click() 249 self.video_play(browser, knowledgeid=item[3:]) 250 251 def index(self, browser): 252 urls = [ 253 'https://mooc1-2.chaoxing.com/mycourse/studentstudy?chapterId=90513632&' 254 'courseId=90513518&clazzid=1425627&enc=f5829a7d36554fc3ae3abfaf3a633f8c', 255 'https://mooc1-2.chaoxing.com/mycourse/studentstudy?chapterId=91418036' 256 '&courseId=91417988&clazzid=1425714&enc=2dc20386d2c8bff4efc353931e841bc6', 257 'https://mooc1-2.chaoxing.com/mycourse/studentstudy?chapterId=86886734&' 258 'courseId=96873026&clazzid=1425718&enc=aeb68c76727e9b63267f5a0b1176c70f'] 259 for url in urls: 260 browser.get(url) 261 self.current_url = url 262 self.video_index(browser) 263 264 # 网站登陆 265 def log_in(self): 266 browser = webdriver.Chrome() 267 browser.get('http://i.mooc.chaoxing.com/space/index') 268 browser.find_element_by_xpath('//*[@id="selectSchoolA"]').click() 269 sleep(1) 270 browser.find_element_by_xpath('//*[@id="26"]').click() 271 sleep(1) 272 browser.find_element_by_xpath('//*[@id="1639"]').click() 273 sleep(1) 274 browser.find_element_by_xpath('//*[@id="unameId"]').send_keys('') 275 browser.find_element_by_xpath('//*[@id="passwordId"]').send_keys('') 276 browser.find_element_by_xpath('//*[@id="numcode"]').click() 277 login_url = browser.current_url 278 while browser.current_url == login_url: 279 print("请输入验证码,然后点击登录。") 280 sleep(5) 281 print('登陆成功,正在跳转至播放页面,请稍等~~~') 282 self.index(browser) 283 284 285 if __name__ == '__main__': 286 erya = AutoErya() 287 erya.log_in()