您的位置:首页 > 理论基础 > 计算机网络

Android客户端利用OKhttp3,Jsoup实现登录教务官网,并获取成绩,课程表等

2017-04-05 11:24 721 查看
本人是大二学生,在寒假写了这个项目,先看下效果,这里展示出了几个重要模块的截图。



第一步

第一步肯定就是在客户端模拟登陆教务处的官网了,只有登录成功才能获取到想要的信息。

要模拟登陆,我们需要需要一个抓包工具——Fiddler,来获取浏览器在登录时候的网络请求,然后在客户端模仿浏览器的请求方式进行登录操作,这里是Fiddler的官网下载链接[]https://www.telerik.com/download/fiddler]

然后我们打开Fiddler,



然后在浏览器中打开学校教务的网站



登陆成功后,我们再返回Fiddler看看发生了什么变化,

发现我们获取到了刚才的登陆请求,原来是一个post请求,那我们就在Android客户端模仿网页登录的方式进行模拟登陆。

我们利用已经成为Android开发者标配第三框架Okhttp进行网络请求。

OKhttp基本功能的实现电梯——

http://blog.csdn.net/m0_37360394/article/details/69230452

现在我们已经导入了Okhttp,接下来就用代码实现模拟登陆。

首先,通过抓包我们发现,浏览器首先通过一个get请求,确认了一个一个重要的信息——cookies,有了cookies,才能进行后续请求访问。



下面的代码就是get请求了主页的验证码,在获取到cookies的同时还把验证码的图片抓了下来,

private void ChangeImage() {
Request request = new Request.Builder()
.url("http://222.24.62.120/CheckCode.aspx")
.build();
okhttp3.Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
Log.i("info_callFailure", e.toString());
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
byte[] byte_image = response.body().bytes();
byte[] Picture = (byte[]) msg.obj;

//把字节数组转化为bitmap

Bitmap bitmap = BitmapFactory.decodeByteArray(Picture, 0, Picture.length);
//session
Headers headers = response.headers();
List<String> cookies = headers.values("Set-Cookie");
String session = cookies.get(0);
cookie=cookies.toString();
s = session.substring(0, session.indexOf(";"));
}
});
}


通过抓取,我们知道了登录所需的参数,重要的txtUserName使我们的学号,TextBox1和TextBox2是我们的密码,txtSecretCode是我们的验证码。万事俱备,只欠东风,就是发送登录的post请求,


post登陆代码:

private void LoginServer() {
num=editTextNum.getText().toString();
FormBody body = new FormBody.Builder()
.add("__VIEWSTATE","dDwtNTE2MjI4MTQ7Oz5O9kSeYykjfN0r53Yqhqckbvd83A==")
.add("txtUserName",学号)
.add("Textbox1",密码)
.add("TextBox2",密码)
.add("txtSecretCode",验证码)
.add("RadioButtonList1","%D1%A7%C9%FA")
.add("Button1","")
.add("lbLanguage","")
.add("hidPdrs","")
.add("hidsc","")
.build();
Request request = new Request.Builder()
.addHeader("cookie", s)
.url("http://222.24.62.120/default2.aspx")
.post(body)
.build();
okhttp3.Call call2 = okHttpClient.newCall(request);
call2.enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
return;
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
/*你想要执行的下一步功能*/
}
}
}


登陆成功! 跳转到功能界面:



然后继续进入官网查询课表成绩,并获取这个参数 __VIEWSTATE,然后用安卓进行模拟查询,这里我给出抓取成绩的方法,其余功能的做法都相似。

我们按照上面的在官网查询成绩,依然通过fiddler抓取要递交参数的列表。

private void getScore() {
new Thread(new Runnable() {

c2b5
@Override
public void run() {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++)
info[i][j] = " ";
}
Document document = null;
try {
document = Jsoup.connect("http://222.24.62.120/xscjcx.aspx?xh="+xh+"&xm="+xm+"&gnmkdm=N121605")
.header("cookie", cookie)
.header("Referer", "http://222.24.62.120/xs_main.aspx?xh="+xh)
.header("Host","222.24.62.120")
.get();
} catch (Exception e) {
e.printStackTrace();
}
viewstate=document.select("input[name=__VIEWSTATE]").val();
try {
document = Jsoup.connect("http://222.24.62.120/xscjcx.aspx?xh="+xh+"&xm="+xm+"&gnmkdm=N121605")
.header("cookie", cookie)
.header("Referer","http://222.24.62.120/xscjcx.aspx?xh="+xh+"&xm="+xm+"&gnmkdm=N121605")
.data("__EVENTTARGET","")
.data("__EVENTARGUMENT","")
.data("__VIEWSTATE",viewstate)
.data("hidLanguage","")
.data("ddlXN",nianji)
.data("ddlXQ",xueqi)
.data("ddl_kcxz","")
.data("btn_xq","%D1%A7%C6%DA%B3%C9%BC%A8")
.post();
} catch (IOException e) {
e.printStackTrace();
}
viewstate = document.select("input[name=__VIEWSTATE]").val();
nianji=document.select("select[name=ddlXN]").select("option[selected=selected]").val();
xueqi=document.select("select[name=ddlXQ]").select("option[selected=selected]").val();
Elements elementsClass = document.select("td");
Elements trs = document.select("tbody").select("tr");
for (int i = 0; i < trs.size(); i++) {
Elements tds = trs.get(i).select("td");
for (int j = 0; j < tds.size(); j++) {
String text = tds.get(j).text();
info[i][j] = text;
}
}
min=info[1][0].substring(info[1][0].length()-6,info[1][0].length()-4);
}
}).start();
}


这样各条成绩信息就已经存String数组中了。

最后一步

把获取到的各条信息放到对应的布局中,就完成了想要的功能。

想要源码的可以联系我Q 973627733
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 网络