一个大学没有自己的移动客户端,不能忍!查成绩,课表考试都要打开网页,不能忍!超级课程表丑陋的UI不能忍!广告不能忍!
那么既然这么多不能忍,那不如我们自己开发一个,当然,指望正方给你提供API那是不可能的了,所以,就只有爬网页了。
用到的工具:
- chrome (用开发者工具抓包)
- Jsoup (解析html)
- okhttputils (网络访问,张鸿洋大神的开源框架)
关于Jsoup
,okhttputils
不会使用的同学,可以自行google。本篇教程还没有使用到Jsoup
;
环境搭建
在Android Studio添加依赖
compile 'com.zhy:okhttputils:2.3.9'
compile 'org.jsoup:jsoup:1.9.1'
登录抓包
- 首先进入你学校的正方管理系统首页,比如我们学校的首页,chrome打开开发者选项;顶部选项卡切换到Network界面;
- 登录你的账号,登录成功后查看chrome开发者工具
黑框中的就是我们需要的,当然有可能你学校的是defaultX,貌似用default1~6 6个页面吧。然后我们点一下他,就会看到具体的Headers信息,这是我们需要的,首先我们先看最下面的Form Data 如图:
这些就是我们请求的表单数据;
前面两个 __VIEWSTATE
,__VIEWSTATEGENERATOR
不知道什么意思,一会直接复制那个值就可以了。
txtUserName : 用户名
TextBox2 : 密码
txtSecretCode : 验证码
RadioButtonList1:用户类型,学生,教师
Button1: 不知道是什么,传一个空字符串就可以了
lbLanguage : 不知道是什么,传一个空字符串就可以了
好了,上面的就是我们需要请求的表单信息,当然,要想在手机上模拟登录,还是不都够了,我们还需要以下的信息 ,可以在Request Headers中得到:
Host:210.44.159.4
Referer:http://210.44.159.4/default2.aspx
在General中得到:
Request URL:http://210.44.159.4/default2.aspx
有了上面的这些信息,我们就可以在手机上请求登录了,激动吧!
等等,那个验证码我们怎么得到呢?
获取验证码
不着急,这个好办;回到正方管理系统首页;鼠标放在验证码上面,然后右键-检查,就会看到:
黑框中的链接就是验证码的url,然后,右键-Copy link address 就可以得到我们的验证码url了,不信的话可以复制到浏览器打开,看是不是我们的验证码呢;
还有个问题就是,我们有时候会因为一些问题需要切换验证码,那么,如何更新验证码呢?
这个也不难,从上图中我们可以看到, 验证码图片有一个onClick()
事件,它触发了一个reloadcode()
方法;然后我们查看网页源代码,找到这个方法,发现是这样的
function reloadcode()
{
var verify=document.getElementById('icode');
verify.src=verify.src+'?';
}
很容易知道,切换验证码,只是在源url后面加了一个 ? ,就可以切换验证码了。
登录
有了这些信息就可以请求登录的了;网络访问我用的是张鸿洋的okhttputils
当然你也可以用别的。
想看看布局,布局简单:
<EditText
android:id="@+id/et_stuid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入学号" />
<EditText
android:id="@+id/et_stupsw"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_code"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:clickable="true"
android:onClick="reloadcode"/>
<EditText
android:id="@+id/et_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="验证码" />
</LinearLayout>
<Button
android:id="@+id/bt_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:onClick="login"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
EditText
用于输入学号密码和验证码,最下面的TextView
用于展示登录后的页面,主要是给大家看看请求登录之后是什么样子。我们先来看看部分代码吧
- 加载验证码
/**
* 加载验证码
*/
private void initCode() {
OkHttpUtils
.get()
.url(codeUrl)
.build()
.connTimeOut(5000)
.execute(new BitmapCallback() {
@Override
public void onError(okhttp3.Call call, Exception e) {
//加载失败
}
@Override
public void onResponse(Bitmap response) {
//设置验证码
ivCode.setImageBitmap(response);
}
});
}
- 切换验证码
public void reloadcode(View view) {
codeUrl += '?';
//修改url后重庆请求验证码
initCode();
}
- 登录
OkHttpUtils.post()
//loginUrl就是你请求登录的url
.url(loginUrl)
//下面数据抓包可以得到
.addParams("__VIEWSTATE", "dDwtMTMxNjk0NzYxNTs7PpK7CYMIAY8gja8M8G8YpGL8ZEAL")
.addParams("__VIEWSTATEGENERATOR", "92719903")
.addParams("txtUserName", stuId) //学号,
.addParams("TextBox2", stuPsw)//密码
.addParams("txtSecretCode", code) //验证码
.addParams("RadioButtonList1", "%D1%A7%C9%FA")
.addParams("Button1", "")
.addParams("lbLanguage", "")
.addHeader("Host", "210.44.159.4")
.addHeader("Referer", "//210.44.159.4/default2.aspx")
.build()
.connTimeOut(5000)
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e) {
//请求失败
}
@Override
public void onResponse(String response) {
System.out.println("onResponse");
//请求成功,response就是得到的html文件(网页源代码)
if (response.contains("验证码不正确")) {
//如果源代码包含“验证码不正确”
System.out.println("验证码不正确");
} else if (response.contains("密码错误")) {
//如果源代码包含“密码错误”
System.out.println("验证码不正确");
} else if (response.contains("用户名不存在")) {
//如果源代码包含“用户名不存在”
System.out.println("用户名不存在");
} else {
//登录成功
System.out.println("登录成功");
tvContent.setText(response);
}
}
});
}
- 权限
最后要记得把权限加上
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- 大功告成
我们跑起来吧;
哈哈,是不是有了,还有模有样的,激动吗?
我们输入信息登录试一试;
我们看一下网页的源代码,是不是包含上面的代码呢,是不是发现了什么,
“欢迎您 :”,“xxx同学”,哈哈,这个就是我们在网页登录成功之后的右上角显示的欢迎信息的源代码。这就说明我们登录成功了。
当然还有的情况就是验证码错误,密码错误以及用户名不存在,同样我们也可以从源代码看出来, 其实在网页上就是显示了一个alert()
的弹窗,里面有提示信息,所以,我们在手机上就很容易判断出事登录成功了,还是登录失败了,然后写上相关的逻辑,我这里就不一一写出来了,交给你吧,其实在上面,我已经给你简单的判断了一下了。
好了,上面的就是今天的内容,后面的内容我将介绍大家最关心的考试查询,成绩查询和课表查询
本教程的Demo我已经托管了Github上;
项目地址:https://github.com/hunao0221/LoginDemo