最近开发关于学校服务类小程序,小程序后台需要从学校的系统获取到各同学的信息,所以语言优先选择了python,并用了Django框架。之前也有写过一些爬虫,但都是用其他语言写的。对python并不熟悉,所以这次开发踩了不少坑,也走了不少弯路。在这里总结一下,分享给同样有需要的人。
学校的登陆流程是这样的:
正确登陆流程应该是上图的那样的,但是如果登陆错误是不会获取到302页的,而是直接返回登陆页,python获取到的状态码也是200。
在这里我就犯了一个很严重的错误,我一直以为我post登陆是正确的,从而把bug定位到【python获取不到302验证页】这个问题上,一开始先百度,得出的答案是在requests.post请求中添加allow_redirects=False来禁止网页重定向,我发现还是没有获取到302页,从而转向更底层的httplib和自定义自己的urlib的重定向类。发现还是不行,困扰了我一天,终于在我祭出fiddler之后,bug慢慢显现出来。
fd第一步:抓包
通过fd分别抓取浏览器和pycharm Post请求包
fd第二步:对比
对比pycharm和浏览器向教务系统服务器发出的请求包内容发现,
username,password,imgcode以及cookies两边都是一样的
而user_lb这个字段两边不一样pycharm请求的是中文浏览器则是乱码
难道就是因为这个字段编码问题导致服务器验证失败?
接下来分析一下pycharm的编码
在python3中默认是Unicode编码,我们在使用requests发送post请求的时候,python会默认使用utf-8编码data表单数据,而学校的表单却是以gbk编码提交,是真的很奇葩,目前来说只有非常古老的网站才采用gbk编码了。
下面我们来改一下代码
postdata = {
'imgcode': input(),
'password':input(),
'user_lb':'学生',----> 'user_lb':'学生'.encode('gbk'),
'username':input(),
}
提示:在Python3中,decode是把二进制字符串解码成Unicode码,encode则是把Unicode码转换成对应的二进制字符串
修改完以后再一次验证
就此困扰了我两天的问题终于成功解决,拿到了sessid,之后通过设置相应的cookies便可以对学生信息页进行相应的操作了。
贴个登陆时序图方便理解吧
总结:我最后只用了【.encode('gbk')】就解决了问题,所以说请求的时候,编码很重要,编码错误很可能导致服务端拿不到正确的请求内容,从而爬虫也接收不到正确的响应内容。
网友评论