本文共 3413 字,大约阅读时间需要 11 分钟。
升级版见:
某天发现正方教务系统突然升级了,以我们学校江南大学为例:
原先有一个BUG访问default3.aspx可以直接跳过验证码,出现的就是仅仅是用户名和密码一个简洁的框子,现在已经被修复了
所以就必须解决验证码的问题了!
基本思路有几个:
所以最后采用的还是手工输入了。
看了一下超级课程表的解决方案,也是一样的,手工输入验证码
开启一个session,完成下面的爬虫工作。确保每次的cookie保持一致。先抓取教务系统首页,然后再一次单独抓取验证码,模拟正常在浏览时看不清验证码刷新一次。将获取的验证码并下载到本地,然后填写验证码,一起将登陆数据post过去,实现登陆。
通过审核元素观察到验证码的地址是:?
网页登陆查看post数据内容
参数说明:
这是.Net框架特有的一个东西,会变化可以从html的源代码中找到这个值
学号参数
密码参数
验证码
这个在rawdata里面是%D1%A7%C9%FA 这个是url编码以后的,反url编码转出来的是 学生
这两个参数均为空值
# author: HuYong#-*-coding:utf-8-*-import osimport refrom lxml import etreeimport requestsimport sys#设置编码reload(sys)sys.setdefaultencoding( "utf-8" )#初始参数studentnumber = "1030614418"password = "342626199509064718"#访问教务系统s = requests.session()url = "http://202.195.144.163/jndx/default2.aspx"response = s.get(url)# 使用正则表达式获取 __VIEWSTATE# __VIEWSTATE = re.findall("name=\"__VIEWSTATE\" value=\"(.*?)\"",response.content)[0]# 使用xpath获取__VIEWSTATEselector = etree.HTML(response.content)__VIEWSTATE = selector.xpath('//*[@id="form1"]/input/@value')[0]#获取验证码并下载到本地imgUrl = "http://202.195.144.163/jndx/CheckCode.aspx?"imgresponse = s.get(imgUrl, stream=True)print s.cookiesimage = imgresponse.contentDstDir = os.getcwd()+"\\"print("保存验证码到:"+DstDir+"code.jpg"+"\n")try: with open(DstDir+"code.jpg" ,"wb") as jpg: jpg.write(image)except IOError: print("IO Error\n")finally: jpg.close#手动输入验证码code = raw_input("验证码是:")#构建post数据RadioButtonList1 = u"学生".encode('gb2312','replace')data = {"RadioButtonList1":RadioButtonList1,"__VIEWSTATE":__VIEWSTATE,"TextBox1":studentnumber,"TextBox2":password,"TextBox3":code,"Button1":"","lbLanguage":""}headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36",}#登陆教务系统response = s.post(url,data=data,headers=headers)print "成功进入教务系统!"
这是登陆后的首页,可从这里提取姓名和学号信息。通过xpath从html中提取即可。
def getInfor(response,xpath): content = response.content.decode('gb2312') #网页源码是gb2312要先解码 selector = etree.HTML(content) infor = selector.xpath(xpath)[0] return infor#获取学生基本信息text = getInfor(response,'//*[@id="xhxm"]/text()')text = text.replace(" ","")studentnumber = text[:10]studentname = text[10:].replace("同学","")print "姓名:"+studentnameprint "学号:"+studentnumber
点击课表访问的页面是
有几个参数xh为学号,xm为姓名,进行了url编码
注意:headers里面有这样一个参数,一个要有,不然会失败
Referer:
2.编码实现:
urlStudentname = urllib.quote_plus(str(studentname.encode('gb2312')))#获取课表kburl = "http://202.195.144.163/jndx/xskbcx.aspx?xh="+studentnumber+"&xm="+urlStudentname+"&gnmkdm=N121603"#必须要有Referer这个参数headers = {"Referer":"http://202.195.144.163/jndx/xs_main.aspx?xh=1030614418","User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36", }response = s.get(kburl,headers=headers)html = response.content.decode("gb2312")print html
已经爬取了课表的html源码,下面正则表达式即可提取具体课表信息。
观察验证码,需要先去除噪点,然后再分割,再ocr识别
转载地址:http://uithj.baihongyu.com/