我们不能失去信仰

我们在这个世界上不停地奔跑...

0%

Python实现校园网模拟登陆

初学python

  • 因为以前有写过C语言,和java的经验,上手python就比较快

    我嫌麻烦,因为看一些公开课的课,时间又比较长,老师讲的又慢,与编程无关的话一大堆,我无法静下心来听他一直扯下去,然后学到的东西还很少,所以就准备找了本书看了一下,我在kindle 上直接搜索的,一本 编程小白的第一本Python入门书 大概花了三个小时跟着把习题都做一遍,把代码都打一遍,差不多就已经入门了。

  • 然后开始准备安装ide,刚接触vim深感其强大,都说vim 是神一样的编辑器 ,emace是神的编辑器,开始打代码都是在vim里打,然后发现一个ide其实也挺不错的,就在ide里用了。毕竟完成一个工作,选择最有利的工具才能事半功倍。

    在知乎上看到一款公认很好的ide pycharm 然后就下载试了试,在mac上,界面比较简洁,还不错。

    开始编程

    准备写个东西练练手,然后就想到我们学校的校园网,一般登陆不需要验证码,那就用python写个模拟登陆页面吧。然后就开始疯狂的查资料,查python常用的库函数,然后看看官方文档,英文有时候实在看不下去了,就去找了一个python中文api翻译的网站,也还不错,选择你需要查看的版本即可查阅。

  • 因为以前用JSP写过校园网模拟登陆的代码,所以就想当然的用同样的思路,移植到python,不一会,也就五六分钟,把代码全部搞定,准备实现模拟登陆,眼看就要大功告成了,可是让我没想到的却是一个星期每天五六个小时的研究为何一直无法登陆成功,效率确实很低,还好我不弄好誓不罢休,别人都能做出来,自己也肯定能做出来。

    开始,先用一款抓包工具进行抓包,查看到底发了什么包,然后与正常登陆的包对比,有一点很重要,每次正常登陆的时候一定要先清除浏览器数据,否则抓到的包有可能不完整,我就是被这一点搞得,所以导入 模拟登陆时时无法成功,浪费了很多的时间。

    因为对python了解的不深,我就尽量对比每个细节,查找可能出错的地方,在包里我发现,他的form数据提交的顺序不一致,因为没有其他办法,我也只能一点一点找差异,一点一点改,利用控制变量法,争取早点把错误找出来,不放过每一点可疑之处 .

    正常浏览器请求数据的顺序:

    正常的浏览器请求

    使用python请求数据的顺序:

    查了一下,是因为python字典默认是无序排列的,但是这并不影响数据的提交,这才松了口气,准备查找另一个不同。

    我的mac用的是charles 抓包工具,然后,又发现,在Headers 里的 Connection:close 查了查 Http Connection 的资料,并没有找到我想要的。

    实在没办法, 我就准备动手做实验,所谓实践出真理嘛,因为一般的抓包工具都会有修改请求重新发送的功能,并且python2.7 urllib2 里面默认就是 close无法修改。

    所以,我就只能从抓包工具那里改了把http请求头Connection改成 Connection:close,然后还有其他数据也要改一下,否则请求不一定成功,比如说我的这个网站,每次登陆的时候他都会在你访问那个登陆页面的时候给你一个checkcode 的值,然后你登陆的时候需要把checkcode一同带上 post上去,否则不会成功,一般而言,本机有cookie,所以cookie应该不用改,先通过浏览器访问登陆页面,在抓包工具里,看看cookie等等和以前一样不,如果不一样,也需要修改cookie,然后再把checkcode改成他给的,然后在抓包工具上,修改上一次登陆成功的包,改变一些值的内容,看看能否成功登陆。每个网站视具体情况而定。

    然后,我都改了,执行,成功登陆了,那么,我就想那就不是 Connection 的值的问题了,然后我就又在苦苦思索,到底是什么让我无法成功登陆。

    接下来的就是枯燥的,分析每一个抓包工具了,我居然都准备拿出抓包顶级神器了,wireshark ,通过wirshark抓包抓,通过过滤筛选,还是一大堆的东西,没办法,只能硬着头皮去一个一个分析,最后还是无果告终。

    继续查看 charles 发现有一个问题,为什么每次 python发的请求,他的response都有一个 set cookie ,这个时候我仿佛就明白了,估计问题就出在这里了,我通过我的经验,想了想,估计有点像局域网arp请求那样,需要确认cookie被使用了,所以,我就查找了cookie的方法,然后进行手动,提取cookie,然后发送和浏览器登录一摸一样的请求,最后发现还是不行,又在想,是不是因为页面请求的多了, 都错乱了,每次发的信息都不一致, 例如这次请求发的是上一次的checkcode,cookie却是这次的,这样就导致了失败,但是,我把他们全部搞的意志,怀着非常期待的心情准备再一次实验的时候,无情的告诉我,又一次失败了,还是老样子。

    彻底奔溃了。这个时候我想,一定是代码的问题。

    我就查阅别人的代码,发现有一个cookie自动处理的东西,不要自己在请求头Headers 里面写cookie,因为初学,有点不太相信,能做到这么只能,当初就没管它,但是还是有些印象的,因为毕竟那是一个我心中的疑问, 所以就怀着半信半疑的心情试了一下,丢弃了JSP拼接的思想,就把好像一个很无关的代码扔了进去,效果很奇特,然后经过重新理清思路,在从浏览器里登陆,分析一个完整过程,调整代码访问顺序,

    当我点开那个请求的response的心情是万分激动的。哇,哈哈哈, 终于这次没有失败了,完成了。那种心情简直能跟表白成功了一样的激动。

    进入正题,源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# -*- coding:UTF-8 -*-
import HTMLParser
import urlparse
import urllib
import urllib2
import cookielib
import string
import re
import md5


# 我那个网站是使用md5加密完在post出去的,大家可以查看网页源代码查看加密的代码

def passwordmd5(src):

m1 = md5.new()
m1.update(src)
print m1.hexdigest()


# 开始就很无知,写了一个手动提取cookie,导致费了很对时间,别人搞好的给你,你都不会用,深感学会使用工具的重要性呀

def get_cookie():
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
response = opener.open('*********')
list = []
for item in cookie:
if item.name == 'JSESSIONID':
list.append('JSESSIONID')
a = '='
list.append(item.value)
str = a.join(list)
return str

# 这个是登陆前请求,应该是要确认cookie,Post的时候带上cookie

def random():
url = '*****'
req = urllib2.Request(url)
res_data = urllib2.urlopen(req)


hosturl = '登陆url'
posturl = '发送请求的链接,抓包工具可以抓到,也可以分析网页源码,不过比较麻烦'

cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)
h = urllib2.urlopen(hosturl)
html = h.read()
# 截取 checkcode 笨方法,其他网站视情况而定
checkcode = html[2990:2994]
random()
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8',
'Accept-Language': 'zh-cn',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': '**************',
}
# 看你要登陆的网站用什么加密代码,我这里是md5
passwordmd5('password')

# 视情况而定,你要登陆的网站需要提交什么数据

postData = {'account': '账号', 'password': '', 'code': '', 'checkcode': checkcode, 'Submit': '登 录'}

postData = urllib.urlencode(postData)
request = urllib2.Request(posturl, postData, headers)
response = urllib2.urlopen(request)
text = response.read()
print text

注:python2.7