大概全中国的教务处网站都是一样的,选课时期总是出去薛定谔的猫的状态,因此使用爬虫来选课对于计算机的学生来说就很正常了,在进行爬虫爬取之前,我们首先需要对它进行抓包分析。
试探
首先登录教务处网址,我们学校教务处的网址是10.5.2.80,在浏览器中输入网址后你会发现进行了重定向,重定向后的网址是10.5.2.80/(uzcntciw0q5jisjv5ydagx45)/default2.aspx.你会发现中间用括号括起来了一个长度为24的字符串,我们再在浏览器中输入一次10.5.2.80网址,再次进行重定向,发现中间的字符串再次进行了改变。这就很有意思,中间的字符串为甚每次登录教务处网址都会改变呢,
当然我们首先进行抓包来看看,浏览器向服务器发送了什么
我们发现请求的地址正是我们每次重定向到的网址
再查看下我们发送的表单
TextBox1、TextBox2中分别存储着我们的用户名和密码那么我们探索一下表单中另外三个参数的作用(PS:这命名随意到难以置信).RadioButtonList1、Button1很明显是url编码的值,我们将RadioButtonList1、Button1中的值进行url解码(注意此处url编码使用了gb2312)。
结果分别为学生和登录。可是另一个VIEWSTATE呢
VIEWSTATE
VIEWSTATE其实也算一个很古老的东西了,正是因为老旧的教务处也同样的古老,我们才能够发现他。正方是使用ASP开发的,而VIEWSTATE也算ASP一个特点(基本存在于已经废弃webform),它起到的作用主要将整个页面的控件的状态用base64编码传给后端,具体可以看浅谈viewstate
VIEWSATE是属性type=hide的input标签,我们按下f12查看它的值
于是我们试着用base64解码VIEWSTATE试试,为了使大家清楚viewstate到底存储了怎样的信息,我们进入信息较多的课表页然后读取它隐藏的VIEWSTATE将其进行解码
手动DOG脸
虽然http协议本身是无记忆的,但是VIEWSTATE能够使它拥有记忆的能力,它能够保留你之前的一系列操作。
注意viewstate是一路变化的,若想完全模拟浏览器,应当在写爬虫跳转时都获取当前页面viewstate
模拟登录的源码
我们先模拟输入10.5.2.80重定向的过程
#!/usr/bin/env python3 #-*- encoding:utf-8-*- import requests from bs4 import BeautifulSoup ? url = "http://10.5.2.80" ? res = requests.get(url) #无需添加header,教务处没有检查 print(res.url) #‘http://10.5.2.80/(ekjnqwuvqxd5hq2whour5n45)/default2.aspx‘
res.url就是我们等会登录请求的地址,再模拟表单提交的过程
#我们使用Beautifulsoup来找到要提交的内容 redirect_url = res.url content = BeautifulSoup(res.content) payload = { "__VIEWSTATE":content.find(attrs={"name":"__VIEWSTATE"}["value"]), "TextBox1":"**",#输入你的账号 "TextBox2":"**",#输入你的密码 "RadioButtonList1":"%D1%A7%C9%FA",#代表你的身份为学生 "Button1":"+%B5%C7+%C2%BC+",#虽然我也不懂按钮也要给value代表提交 } res = requests.post(redirect_url,data=payload) print(res.text)
你会发现你已经登录进入了教务处
不存在cookies的会话保存
如果你之前用过requests一定不会陌生session,我们知道http协议是无记忆连接那么他是如何保存一个用户的信息的呢?
答案在于cookies。
一般的登录在登陆后会的响应头中会有这么一行
Set-Cookie: *************
表示增加该cookie,浏览器收到这个响应后,会存储这个cookie到本地,在请求这个网站时,头部会自动携带这个cookie
后端会检查浏览器的cookie判断是否是用户
因此我在最初使用时,就用了自动处理cookies的requests.session,但是我发现我根本是多此一举
因为
它根本没有保存任何cookies!!
于是我陷入了深深的沉思。
还记得前面我们提过的那个奇怪的长度为24的字符串吗?
没有错,那个括号就是对你身份的标示。
不负责任的猜测:后台数据库在你登录后会随机分配一个hash后的字符串,然后重定向,如果登录成功,则在后台将这个字符与你账号对应,一旦中间字符是这个则表示是你登录
所以你将这个网址发给你的同学,直接连接这个网址就是你的登录界面了。
奇怪的GET
顺便提一句教务处不兼容现代浏览器的原因是因为它的下拉子菜单用了已经被废弃的IE标签,写个JS脚本替换下就可以
以选课页面为例子,你点击它会弹出子标签页,而当我将弹出的子标签页的网址输入在浏览器中发现它却把我重定向回了登录界面(浏览器的开发者工具不监听弹出子页面),难道不是get。
于是我打开了burpsuit比较了这两个包的差异
你发现了有什么不同吗?
就在于被我多标红的那一栏Referer
最后的抢课请求
其实没有好说的,抢课的请求页面和你浏览课程的页面是一样的,网址都是
http://10.5.2.80/(×××××××)/xf_xsqxxxk.aspx?xh=××××××&xm=×××××××&gnmkdm=N121109
区别在于请求方式和referer
只要老实查看表单模拟表单提交就可以了
全部脚本
别想了,怎么可能给你全部的脚本,自己去写吧!
或说写这么长的文章早可以把教务处管理员JWC01的密码爆破出来