今天这篇文章为大家带来的是模拟登录教务系统并抓取课表和成绩的详细实现过程。这个程序基于Android平台,大致的流程是首先使用OkHttp3网络请求框架来模拟登录教务系统,然后利用Jsoup库来解析获取到的html代码,最后只要处理下数据将其显示到界面上就可以了。运行程序后的效果如下图所示:
大家想看完整的源代码,可到文末的链接下载。之前也写过一个类似的程序,不过用的是HttpClient来进行网络请求,Android 5.0中已将其废弃,而Android 6.0也已移除了其相关的类,而且之前用的编辑器还是Eclipse,所以我重新编写了代码,使用Android Studio编辑程序,并换用了OkHttp库,我的上一篇文章:Android Studio从安装到配置,也刚好就能以这个项目作为实战程序,还能顺带熟悉下Android Studio。准备这篇文章我也挺用心的,有什么问题或者文章有什么错误都欢迎大家提出来,一起讨论交流,相互学习。
下面让我们先来捋一捋这篇文章所要分享大家哪几个方面的内容:
1. 如何使用HttpWatch工具,查看GET请求的地址,POST请求需要传递哪些参数,怎么设置header等等;
2. OkHttp3的基本使用方法,如何自动化管理Cookie等;
3. Jsoup的基本使用方法,用法很灵活,可通过DOM,CSS以及类似于jQuery的操作方法来操作数据;
4. 程序界面的设计。
接下来就正式开始进行详细说明了。
1. HttpWatch的使用方法
以前HttpWatch只能在IE浏览器中使用,现在也可以集成到火狐浏览器中使用。如果不想使用HttpWatch进行抓包,也可以使用Fiddler,这个工具也很强大。我们这里就还是介绍HttpWatch的用法,具体的打开方式是安装好HttpWatch Professional Edition后—>打开IE浏览器,点击“查看”这个菜单项—>选择“浏览器栏”—>最后选择“HttpWatch Professional”即可。成功打开后,现在就访问教务系统页面吧。点击Record按钮就可以开始抓包了。
P.S. 因为今年刚毕业,帐号已经被注销了,这里为了分享给大家这个程序的实现过程,找学弟借的帐号,下面相关的信息就打上马赛克了。
1.1 验证码
1.1.1 请求地址
以前正方教务系统有个bug,在用户名和密码都正确的情况下,登录时验证码直接传空值也能成功登录,这几天写代码的时候发现这个bug已经修复了,不正确填写验证码已经不能成功登录了。那我们先来看看验证码的请求地址吧,确保点击了Record按钮后,点击登录界面上的看不清换一张,从HttpWatch记录的信息可以知道发送了GET请求,这里我们最需要关心的是获取验证码的请求地址。
注:这里获取验证码和后面登录的操作,用的都是同一个Cookie。我后面会介绍怎么使用OkHttp自动化管理Cookie,所以这里的Cookie值是什么,不必关心。
1.2 登录系统
1.2.1 请求地址
填好用户名,密码及验证码后点击登录按钮,登录成功后,发现发送了POST请求,与GET请求不同的是我们不仅仅要关注请求的地址,还要关心请求Header以及Post的数据,而这三项可以分别在HttpWatch中的Overview, Header和POST Data这三个选项卡中查看。这里我们看到登录成功后,状态码是302,而不是200,说明这里进行了重定向,稍微关注一下,后面会提到我们的特殊处理。
1.2.2 请求头
同样的Cookie不用管,Headers我们就只用关心下面这三项。
注:现在我们来看看之前提到的状态码为302的问题,我们能发现302请求下面那个GET请求的URL和你浏览器地址栏的网址是一样的,也就是我们点击登录后,数据是发送给302那个地址的,最后才重定向到这个200的地址来。所以我们后面设置登录的Header时,Referer的值就直接设置这个状态码为200的地址就可以了,数据验证成功后直接跳转到这儿。
点击POST请求的Content标签页就能进一步验证我们的想法,这个是请求302那个地址成功后页面html代码,也就是说当数据验证成功后,会跳转到a标签的href属性里的地址,那个地址也就是200的GET请求URL,即系统主页,所以Referer直接设置它就行。
1.2.3 POST数据
POST的数据就每一条都要传了,没有值的传空字符串即可。
RadioButtonList1的值为乱码,我们可以去登录界面查看源代码就可以发现,RadioButtonList1是一个table的id,而我们登录时选择的是表格里的一个RadioButton,它的value是”学生”,所以我们后面传递参数的时候设成"学生"即可。
其实__VIEWSTATE也是通过取页面上控件的值所得,这个值据说是.net自动生成的,一般来说同一个页面,这个值不会变,不过我后面请求登录的时候还是每次都去取值,你也可以选择就用这个抓取到的数据,也是完全可以的。
1.3 查询课表
1.3.1 请求地址
1.3.2 请求头
还是这三个参数,只是跳转的Referer不同而已。
1.3.3 POST数据
__EVENTTARGET的值会根据你点击页面上的下拉框,最后改变的值学年还是学期来决定,如果最后点的是学年,值为xnd,点的是学期,值变为xqd。xnd是你所要查询的学年值,xqd是你要查询的学期值,而剩下的两个参数和之前一样,也是取得页面的固定的value值,后面请求就直接用抓取到的数据就行。
1.4 查询成绩
1.4.1 请求地址
1.4.2 请求头
1.4.3 POST数据
ddlXN是你所要查询的学年值,ddlXQ是你要查询的学期值。那个乱码的值,是之前所点击按钮"按学期查询"的value值,和之前一样查看源代码就能看到value,剩下的还是页面上的固定值,请求时直接用就行。