在github上发现一个古老的华医网考试脚本(https://github.com/lhzzzzzz/autoexamofhuayi),是python2写的。它实现了华医网自动登录、自动获取考试编号cwid、自动考试。现在把它翻新一下。
脚本功能基于已知的考试编号cwid,进行华医网自动考试。
需要用到的工具(开发环境)1、Google Chrome;
2、Fiddler:用于抓包;
3、PyCharm
思路分析一、答题流程分析
已有现在的Javascript脚本(《华医网自动答题脚本》),根据华医网的答题代码,进行自动答题。但这个代码使用的是试错了,反复提交需要消耗时间,不适合批量操作。
根据GitHub现有脚本(https://github.com/lhzzzzzz/autoexamofhuayi),发现华医网是直接把原答案放在试题的网页中
所以其实在答题界面,用chrome的F12进行Inspect,也能找到正确答案。
name="gvQuestion$ctl03$result" 对应的 value即正确答案的value
通过Fiddler抓包可以看到,考试主要包括三个动作:
1、GET 考试试题
2、POST 考试试题+答案
3、GET 考试结果
而其中
POST答案提交的data包括以下几部分:
1、__EVENTTARGET 等是 ASP.Net 相关验证参数:可以从考试界面的网页中用正则表达式提取;其中留空的字段可以不提交
2、Hidden1、Hidden2、Hidden3:表示最前面的课程评价星级,可以不提交;
3、gvQuestion$ctl03$question_id、gvQuestion$ctl03$result、gvQuestion$ctl03$rbl :表示题号、正确选项、考生选项(这里当然是直接提交正确选项的value)
二、模拟登录华医网
根据旧的py脚本,以前的华医网登录不需要验证码,现在有了图片验证码,登录变得麻烦了。还是改成手动复制Fiddler抓到的cookie吧
参考:https://github.com/ZhaoKangming/Generate_CME_data_report/blob/master/get_cme_course_info.py
https://github.com/ZhaoKangming/HuaYi
三、Session会话保持
华医网登录之后使用Session进行对话,获取考卷、提交考试、获取成绩都会刷新cookie,而且只有最新的cookie能进行下次对话。
所以这里需要用requests.session()保持会话,而且起始的cookie必须是最新的一个cookie
使用流程(代码实现)# 原代码地址:https://github.com/lhzzzzzz/autoexamofhuayiimport requestsimport re# 设置Fiddler代理proxies = { "http": "http://127.0.0.1:8888", "https": "http://127.0.0.1:8888",}session = requests.session()# 打开 cookie.txt,复制最新一次对话的cookieswith open("cookie.txt", "r") as file:cookie = file.read()headers = {'Accept': '*/*','Accept-Encoding': 'gzip, deflate','Accept-Language': 'zh-CN,zh;q=0.8','Connection': 'keep-alive','Host': 'cme3.91huayi.com','Content-Type': 'application/x-www-form-urlencoded','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}headers['Cookie'] = cookiesession.headers = headersdef post_exam(cwid):url = 'http://cme3.91huayi.com/pages/exam.aspx?cwid='+cwidexam_content = session.get(url,proxies=proxies)print(exam_content.text)#选项namepattern4 = re.compile(r'')match5 = re.findall(pattern5, exam_content.text)pattern6 = re.compile(r'id="__VIEWSTATE" value=".*?/>')match6 = re.findall(pattern6, exam_content.text)pattern7 = re.compile(r'__EVENTVALIDATION" value=.*?/>')match7 = re.findall(pattern7, exam_content.text)exam_result = {'__VIEWSTATE':match6[0].split('"')[3],'__VIEWSTATEGENERATOR':'265B8D93','__EVENTVALIDATION':match7[0].split('"')[2],'btn_submit.x':'0',# 系统用于检查用户有没有选择'btn_submit.y': '20'}for ia in range(int(len(match5) / 2)):print(ia)exam_result[match4[ia]] = match5[ia*2][1] #rblexam_result[match5[ia*2][0]] = match5[ia*2][1]exam_result[match5[ia*2+1][0]] = match5[ia*2+1][1]headers['Referer'] = urlsession.headers = headers# 提交考试r = session.post(url, data=exam_result,proxies=proxies)# print(r.text)# 获取考试结果result = session.get('http://cme3.91huayi.com/pages/exam_result.aspx?cwid=' + cwid,proxies=proxies)print(result.text)cwids =[] # 考试id列表for cwid in cwids:print(cwid)post_exam(cwid)运行结果如果全部考完,可以在网页中看到可以申请证书。
MORE华医网很多bug的,如没有完成考试也可以直接申请证书,在考试结果页面,浏览器状态输入代码就可以。
javascript: window.location.href = 'apply_certificate.aspx?cid=73058c85-868c-484c-b95d-a82dccfd468d'