如果你是在校大学生,或许你用多了各种课程表,比如课程格子,超级课程表。它们都有一个共同点就是可以一键导入教务处的课程。那么一直都是用户的我们,没有考虑过它是如何实现的。那么现在就来模仿一款”超级课程表“。
PS:由于超级课程表是商用软件,原本提取了一些图片,但是为了避免涉及侵权问题,所有图片均已使用一张绿色圆圈代替,背景图片也以颜色代替,缺乏美观,如果你觉得太丑,可以自己寻找图片代替。
那么说了这么久,先来看看这款高仿的软件长什么样子。本文的代码做过精简,所以界面可能有出入。
好了,界面太丑,不忍直视,先暂时忽略,本文的重点不是UI,而是如何提取课程。
先做下准备工作。
-
HttpWatch抓包分析工具。此工具的使用后文介绍
-
Litepal数据持久化orm,郭大神的大作,挺好用的orm,用法详见郭霖博客。
-
Async-android-http 数据异步请求框架,这里主要用到这个框架的异步请求以及session保持的功能,或许大多数人没有使用过这个框架的会话保持功能,反正个人觉得就是一神器,操作十分简单,就1句话,不然用HttpClient可能就没那么简单了,要自己写好多内容。具体用法参见github
-
Jsoup网页内容解析框架,可支持jquery选择器。可以支持从本地加载html,远程加载html,支持数据抽取,数据修改等功能,如果能灵活运用这个框架,那么你想抓取什么东西都不在话下。
既然要导入课程表,那么一定要登录教务处,结论是需要教务处的账号密码,这个好办,每个学生都有账号密码。那么怎么登录呢,这个当然不是我们人工登录了,只要提供账号密码,由程序来帮我们完成登录过程以及课程的提取过程。如果登录?首先打开教务处登录界面,打开HttpWatch进行跟踪。输入账号,密码,验证码(验证码视具体学校不同,有些学校不含验证码,有些学校含验证码,验证码的处理后文进行说明),输入完成后点击登录,再点击查看课程的菜单,之后停止HttpWatch录制,把文件保存一下进行分析。打开保存后的文件,查看登录时提交的参数及一些信息,记录下来,同时记录查看课程页提交的参数及信息。
先看登录页面提交的参数,参数均是POST提交,这可以通过HttpWatch看到提交方式
__VIEWSTATE:有这个值页面生成的,这里我直接使用这个固定值而不去抓取,这个值是.net根据表单参数自动生成的。理论上同一个页面是不会变动的。
Button1:传空值即可
hidPdrs:传空值即可
lbLanguage:传空值即可
RadioButtonList1:图上是乱码,通过查看网页源代码可知该值是学生,因为我们是以学生的角色登录的
TextBox2:这个值是密码,传密码即可
txtSecrect:这个值是验证码,传对应的验证码即可
txtUserName:这个值是学号,传学号即可
你以为只要提交这些参数就好了吗,那么你就错了,我们还有设置请求头信息,如下图
我们不必设置所有请求头信息,只需要设置Host,Referer,User-Agent(可不设)。
请求头设置完毕了,那么来说一个重大的问题,就是验证码的问题,这里有三种方式供选择。
-
在登录之前抓取验证码,显示出来,供用户输入。
-
使用正方的bug1,为什么是bug1呢,因为后面一种方法利用了bug2,bug1,bug2不一定所有学校适用,正方的默认登录页面是default2.aspx,如果这个页面有验证码,你可以试试default1.aspx-default6.aspx六个页面,运气好的话可能会有不需要验证码的页面。这时候你使用该页面进行登录即可(提交参数会不同,具体自己抓包分析)
-
使用正方的bug2,不得不说这个bug2,大概是某个程序猿在某男某月某日无意间留下的把,那么怎么使用这个bug呢,很简单,登录的时候直接传验证码为空值或者空字符串过去就好了,有人说,你他妈逗我,这都行,恩,真的行。为什么行呢,原因可能是正方后台程序没有判断传过来的值是不是空。我们模拟登录的时候并没有去请求验证码的页面,所有不会产生验证码(此时为空字符串或者空值)和cookie,当我们提交空验证码时,后台接收到的值就是空字符串,两个空字符串做比较当然相等了,以上只是猜测,毕竟正方是.net的,.net的处理机制本人不是很清楚。
说了这么多理论知识,来点实际的把,先完成登录界面的代码
-