1.准备
使用到的开源库有:OkHttputils,JSoup
思路:post方式发送学号,密码,验证码到教务系统,持久化cookie,利用Jsoup解析返回的html,通过特定的标签内容,确定是否登陆成功。
每个校园教务系统登陆可能不一样。
2.查看教务登录所需信息
浏览器进入教务网址,F12可以打开开发者工具,查询html源码
我们可以先在浏览器上进行登录,查看请求头中需要发送的数据,谷歌浏览器在NetWork--->Headers中查看详细的请求信息
可以看到,FormData中:WebUserNO指学号参数,Password指密码,Agnomen指验证码,其他两个是非必要参数。
这时在浏览器上进行登录操作后,可以看一下服务器返回的信息,以进行下一步的解析操作.在NetWork--->Response可以看到服务器返回的html源码。
登录成功返回的例子:
登录失败的例子:
可以看到:在登录成功时,我们可以通过Jsoup判断 第一个table下的第一个td标签下是否为“您好!欢迎您登录教务处网络平台”,来验证用户是否输入了正确的学号,密码和验证码。
而在登录失败时,则会弹出一个提示框提示错误信息,我们可以通过Jsoup解析到<script>标签,判断错误的类型,这样就可以区分是学号还是密码或是验证码输入错误(不同的教务系统的反馈信息不同,自行修改)
Jsoup中文文档:点击打开链接
3.代码示例
Application中配置okhttp的cookie保存方式
//okhttp持久化cookies配置,保存到内存中,退出销毁--PersistentCookieStore保存到本地
CookieJarImpl cookieJar = new CookieJarImpl(new MemoryCookieStore());
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.connectTimeout(time, TimeUnit.MILLISECONDS)
.readTimeout(time, TimeUnit.MILLISECONDS)
.build();
OkHttpUtils.initClient(okHttpClient);
在进入登录页时先去请求图片验证码
/**
* 这里用okhttp请求图片验证码是为了保存下cookie
*/
@Override
public void requestRexPic() {
if (NetUtil.isConnected()) {
this.showProgress("正在获取验证码...");
OkHttpUtils.get().url(Urls.SCHOOL_GET_REGPIC).build().execute(new BitmapCallback() {
@Override
public void onError(Call call, Exception e, int id) {
hideProgress();
}
@Override
public void onResponse(Bitmap response, int id) {
hideProgress();
ivReg.setImageBitmap(response);
}
});
} else {
this.showFailMsg("当前无网络");
}
}
拼装请求头,发送登录请求。解析返回的html
/**
* 登录,拼装请求头
* @param stuId 学号
* @param pwd 密码
* @param regNum 验证码
*/
@Override
public void loginEt(String stuId, String pwd, String regNum) {
params = new HashMap<>();
params.put(FORM_DATA_STUID, stuId);
params.put(FORM_DATA_PWD, pwd);
params.put(FORM_DATA_Agnomen, regNum);
if (NetUtil.isConnected()) {
iLoginEtView.showProgress("正在登录,请稍候...");
iLoginEtModel.loginEt(new LoginEtCallback() {
@Override
public void success() {
iLoginEtView.hideProgress();
iLoginEtView.loginSuccess();
}
@Override
public void fail(String msg) {
iLoginEtView.hideProgress();
iLoginEtView.showFailMsg(msg);
}
}, params);
} else {
iLoginEtView.showFailMsg("当前无网络!");
}
}
/**
* JSoup解析服务器返回的信息
*
* @param data
* @return 登录成功或失败的原因
*/
private String checkData(String data) {
try {
//html转为一个Document对象
Document document = Jsoup.parse(data);
//获取table下第一个tr标签
Element tr = document.select("table").select("tr").first();
//获取tr标签下的第一个td标签
Element td = tr.select("td").first();
//信息填写正确登录成功
if (td.text().equals(LOGIN_SUCCESS_INFO)) {
return LOGIN_SUCCESS;
} else {
//获取script标签内的内容
Elements js = document.getElementsByTag("script");
//最后一组script内容,以 " 分割获取提示的错误信息内容,详细参考校园网址
String[] errorInfo = js.last().data().toString().split("\"");
if (errorInfo[1].equals(USER_OR_PWD_ERROR_INFO)) {
return USER_OR_PWD_ERROR;
} else if (errorInfo[1].equals(REGNU_ERROR_INFO)) {
return REGNU_ERROR;
}
return LOGIN_FAIL;
}
} catch (Exception e) {
e.printStackTrace();
}
return LOGIN_FAIL;
}
到这里,我们就成功登入了教务系统,再拉取课表什么其他的信息的时候,会自动带有cookie,不会出现访问失败的问题。
如果有对这部分源码感兴趣的童鞋:
点击打开链接
本文地址:http://blog.csdn.net/prodigalwang/article/details/61620144