Python3.4 模拟登录校园网 技巧和大坑记录 无验证码
2014-09-10 19:30
676 查看
最近深感python重要,加之raspberry上也需要,关键是能全力地解决问题而不是把时间耗散在实现的细节上,对于完成模型什么的还是非常牛的,于是先写一个模拟登陆来练练手。一开始就挑软柿子捏吧,选了学校的选课网站。无验证码。准备下一次挑个有验证码的玩玩
先把重要的技巧写出来吧,我的的是python3.4,最新版,各种碰壁各种坑,但索性一个个克服过来了,
首先推荐的是http://www.crifan.com/note_about_website_crawl_and_emulate_login/ 这位大神的文章,各种模拟登陆的技巧啊哈哈,本人也受益良多。以下有些部分也是重复的,不过都是自己实际碰上的坑,而且是python3.4版本的,所以还是写下来作为记录
一、辅助工具:wireshark:过滤器那里调到http,然后关闭其他无关的浏览器等等程序,然后再跑python程序,就能很舒服地对python发出的数据包进行查看了哦!当然也可以用Fiddler这个程序,不过urlopen请求的时候要设置代理
2、Fiirebug,调试JS,查看数据包,审查元素什么的都不在话下。不过不能查看python发送的数据包,所以还是需要wireshark配合
二、IDE 推荐Pycharm,知乎上好多人推荐那我也用这个鸟
三、python3对于python2 的改动非常多,而网络上现有的代码大多是基于python2的,所以做好改错的心理准别。如果不想把时间浪费在上面那么就建议直接使用python2,.7版本。其实不能向下兼容真的是一大败笔,尽管设计更加科学了,最大的改动无疑就是urllib模块了,以前杂乱无章的层次被改成了现在的urllib.parser urllib.request 比如urllib.request.urlopen这样的,cookie模块变成了 http.cookiejar ,具体的查看下方源码吧。
五、编码问题:
首先是总结一下对于编码的做法:python内部用的是unicode,而如果要向外输出,那就需要编码(encode),比如UTF8 UTF16 GBK这类的,如果输入(比如从网络上抓取的网页,比如文件的读取),就需要解码成unicode,然后才能愉快的在python里头显示出各种字符,否则UTF8没有经过解码,直接print,如果英文还算正常,中文的话就会出现\xab\x21\x5b 这样的十六进制表示(三组一个汉字)。于是总结出的通用处理方法就是,输入时候统一解码成unicode,输出时候再统一编码成需要的编码
编码还算是挺容易的,string有encode函数,这在python3 python2一样
但是解码就不一样了
在python3里头已经去掉了decode()这个函数了,这个时候
关于编码的问题如果想深入了解可以参考http://blog.csdn.net/kiki113/article/details/4062063 不过这篇文章仍旧是2.x版本的做法,不过原理并无二致
https://mail.python.org/pipermail/tutor/2014-February/100119.html 在python这个邮件组里头也有过2.x版本和3.x版本编码的讨论,觉得非常赞。文章里提到
With the move from Python 2 to Python 3 string handling was changed
py2 --> py3
-----------------
str --> bytes
unicode --> str
意思就是原来py2的str到python3就是bytes对象,原来的unicode成了python3的str
六、cookie头部设置问题:如果期望http.cookiejar自动在请求包header里附加cookie项目,那你就绝对不要手动在header里头设置cookie,否则是不会自动加上cookie的
以下是错误示范
八、有些待发送数据的生成是依靠javascript代码的,比如时间戳,比如密码的加密传输。这就靠firebug,各种审查元素,各种断点来调试出来了。
比如这一次就比较容易,密码
九、并不是所有界面都会派发session的cookie的。这次这个登录界面就没有。难道是post用户密码时候根本就不对有没有session进行检查吧?
十
tip说完了就直接上源代码了。涉及隐私部分一律xxxxxxxxx代替,仅仅提供模板的作用,因为各个网站千差万别。
先把重要的技巧写出来吧,我的的是python3.4,最新版,各种碰壁各种坑,但索性一个个克服过来了,
首先推荐的是http://www.crifan.com/note_about_website_crawl_and_emulate_login/ 这位大神的文章,各种模拟登陆的技巧啊哈哈,本人也受益良多。以下有些部分也是重复的,不过都是自己实际碰上的坑,而且是python3.4版本的,所以还是写下来作为记录
一、辅助工具:wireshark:过滤器那里调到http,然后关闭其他无关的浏览器等等程序,然后再跑python程序,就能很舒服地对python发出的数据包进行查看了哦!当然也可以用Fiddler这个程序,不过urlopen请求的时候要设置代理
2、Fiirebug,调试JS,查看数据包,审查元素什么的都不在话下。不过不能查看python发送的数据包,所以还是需要wireshark配合
二、IDE 推荐Pycharm,知乎上好多人推荐那我也用这个鸟
三、python3对于python2 的改动非常多,而网络上现有的代码大多是基于python2的,所以做好改错的心理准别。如果不想把时间浪费在上面那么就建议直接使用python2,.7版本。其实不能向下兼容真的是一大败笔,尽管设计更加科学了,最大的改动无疑就是urllib模块了,以前杂乱无章的层次被改成了现在的urllib.parser urllib.request 比如urllib.request.urlopen这样的,cookie模块变成了 http.cookiejar ,具体的查看下方源码吧。
五、编码问题:
首先是总结一下对于编码的做法:python内部用的是unicode,而如果要向外输出,那就需要编码(encode),比如UTF8 UTF16 GBK这类的,如果输入(比如从网络上抓取的网页,比如文件的读取),就需要解码成unicode,然后才能愉快的在python里头显示出各种字符,否则UTF8没有经过解码,直接print,如果英文还算正常,中文的话就会出现\xab\x21\x5b 这样的十六进制表示(三组一个汉字)。于是总结出的通用处理方法就是,输入时候统一解码成unicode,输出时候再统一编码成需要的编码
编码还算是挺容易的,string有encode函数,这在python3 python2一样
但是解码就不一样了
在python3里头已经去掉了decode()这个函数了,这个时候
request = urllib.request.Request('http://xxxxxxxxxx',None, headers1) response = urllib.request.urlopen(request) text = response.read()text得到的是bytes字节数组,目前较好的的做法(不知道有没有其他更好的方法呢?)是
text.decode("utf-8") 或者 str(text,encoding='utf-8')byte数组有decode方法来解码bytes对象
关于编码的问题如果想深入了解可以参考http://blog.csdn.net/kiki113/article/details/4062063 不过这篇文章仍旧是2.x版本的做法,不过原理并无二致
https://mail.python.org/pipermail/tutor/2014-February/100119.html 在python这个邮件组里头也有过2.x版本和3.x版本编码的讨论,觉得非常赞。文章里提到
With the move from Python 2 to Python 3 string handling was changed
py2 --> py3
-----------------
str --> bytes
unicode --> str
意思就是原来py2的str到python3就是bytes对象,原来的unicode成了python3的str
六、cookie头部设置问题:如果期望http.cookiejar自动在请求包header里附加cookie项目,那你就绝对不要手动在header里头设置cookie,否则是不会自动加上cookie的
以下是错误示范
headers1 = {'User-Agent': ' Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': ' zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3', 'Referer': 'http://xxxxxxxx', 'Connection': 'keep-alive', 'Content-Length': '0', 'Content-Type': ' application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest' 'Cookie':'xxxxxxx' }七、仍旧是header的设置问题。不要设置Accept-Encoding项目,否则你还要自己解压完才能识别编码,时间宝贵,多一步不如少一步不是?
# 'Accept-Encoding': 'gzip, deflate',#大坑。加入后要手动对gzip解压后才会有可识别的内容八、关于如何调试cookie,可以用wireshark抓包,也可以
cj = http.cookiejar.LWPCookieJar() -------省略若干行------------ if cj: for cookie in cj: print(cookie)因为cookiejar是一个可迭代对象(sdk手册里提到),所以可以用迭代器遍历所有cookie并且打印咯
八、有些待发送数据的生成是依靠javascript代码的,比如时间戳,比如密码的加密传输。这就靠firebug,各种审查元素,各种断点来调试出来了。
比如这一次就比较容易,密码
makeTransferPwd: function (name, pwdPlain){ dojo.require("dojox.encoding.digests.MD5"); var dxd=dojox.encoding.digests; var inp= "NS" + name + pwdPlain; var r_hex= dxd.MD5(inp, dxd.outputTypes.Hex); return r_hex; },太直观了吧。。md5加密的NS+用户名+密码 字符串。python的hashlib库分分钟解决啊有木有。
九、并不是所有界面都会派发session的cookie的。这次这个登录界面就没有。难道是post用户密码时候根本就不对有没有session进行检查吧?
十
tip说完了就直接上源代码了。涉及隐私部分一律xxxxxxxxx代替,仅仅提供模板的作用,因为各个网站千差万别。
# coding=utf-8 import urllib import hashlib import http.client import http.cookiejar import http.cookies #post数据接收和处理的页面(我们要向这个页面发送我们构造的Post数据) posturl = 'http://xxxxxxxxxxxx/xxxxxx.do' #从提交数据包中分析出,处理post请求的url #设置一个cookie处理器,它负责从服务器下载cookie到本地,并且在发送请求时带上本地的cookie cj = http.cookiejar.LWPCookieJar() cookie_support = urllib.request.HTTPCookieProcessor(cj) opener = urllib.request.build_opener(cookie_support, urllib.request.HTTPHandler) urllib.request.install_opener(opener) #打开登录主页面(他的目的是从页面下载cookie,这样我们在再送post数据时就有cookie了,否则发送不成功,当然有的网站也不对此做要求,那就省去这一步) h = urllib.request.urlopen('http://xxxxx.edu.cn/ntms/index.do') #构造header,一般header至少要包含一下两项。这两项是从抓到的包里分析得出的。 headers = {'User-Agent': ' Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': ' zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3', # 'Accept-Encoding': 'gzip, deflate',#大坑。加入后要手动对gzip解压后才会有可识别的内容 'Referer': 'http://xxxxx/userlogin.jsp?reason=login', 'Connection': 'keep-alive', 'Content-Type': 'application/x-www-form-urlencoded', } #构造Post数据,也是从抓大的包里分析得出的。 postData = {'j_username': 'xxxxxxxx', 'j_password': 'fc5700426c8d6a74b0cdf987b63922d3', #你的密码,密码可能是明文传输也可能是密文,如果是密文需要调用相应的加密算法加密,需查看js代码 #才知我就直接硬编码了 'save_cookie': 'none' } #需要给Post数据编码 postData = urllib.parse.urlencode(postData).encode(encoding='UTF-8') #通过urllib.request提供的Request方法来向指定Url发送我们构造的数据,并完成登录过程 request = urllib.request.Request(posturl, postData, headers) response = urllib.request.urlopen(request) text = response.read() #测试是否成功登陆,这里是请求用户信息,如果成功登陆,那么cookie发到这个页面之后就会返回用户资料,否则提示错误,也知道自己登陆失败了 headers1 = {'User-Agent': ' Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': ' zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3', # 'Accept-Encoding': 'gzip, deflate',#大坑。加入后要手动对gzip解压后才会有可识别的内容 'Referer': 'http://xxxx.edu.cn/ntms/userLogin.jsp?reason=logout', 'Connection': 'keep-alive', 'Content-Length': '0', 'Content-Type': ' application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest' } request = urllib.request.Request('http://xxxx.edu.cn/action/getCurrentUserInfo.do', None, headers1) response = urllib.request.urlopen(request) text = response.read() #打印回应的内容 print(str(text, encoding='utf-8', errors='strict'))
相关文章推荐
- python模拟登录有验证码的网站记录
- 利用python3.4爬取学校教务系统,并封装成api供app调用(二)之不带验证码模拟登录
- Python爬虫模拟登录带验证码网站
- Python模拟登录验证码(代码简单)
- Python爬虫模拟登录带验证码网站
- Python爬虫模拟登录带验证码网站
- Python中运用random函数模拟用户登录验证码
- Python模拟登录(带验证码)
- 在Python中用Request库模拟登录(三):Discuz论坛(未加密,有验证码,有隐藏验证)
- Python爬虫实战之爬取链家广州房价_04链家的模拟登录(记录)
- Python爬虫:模拟登录带验证码网站
- Python模拟登录验证码(代码简单)
- 在Python中用Request库模拟登录(一):字幕库(无加密,无验证码)
- 在Python中用Request库模拟登录(二):博客园(简单加密,无验证码)
- 【Python3.6爬虫学习记录】(八)Selenium模拟登录新浪邮箱并发送邮件
- python爬虫实战(四)--------豆瓣网的模拟登录(模拟登录和验证码的处理----scrapy)
- Python爬虫模拟登录带验证码网站
- python爬虫模拟登录之验证码
- 在Python中用Request库模拟登录(四):哔哩哔哩(有加密,有验证码)
- 用wininet库模拟cookie方式验证码登录