本人android新人,学习android2个月了,最近想对学校教务网站进行分析,了解到了模拟登陆
以前对网页的内容了解挺少的,最近才学习的一些东西,有错误的地方敬请批正。
准备工具:httpwatch抓包软件(httpwatch在win10下最新版有兼容问题,我用的是7.0专业版)
okhttp3包:在AS的gradle中导入以下代码
compile 'com.squareup.okhttp3:okhttp:3.10.0'
3.10.0是我做的时候最新版,可以到okhttp的GitHub看下最新版:https://github.com/square/okhttp
okhttp官网:http://square.github.io/okhttp/
一.模拟登陆原理
网页传输的方式一般有get和post, 在httpwatch中你可以看到每个网页的传输方式
这是我校OA网站:http://myportal.sit.edu.cn/
我将账号密码填写后,先看下httpwatch得数据
仔细看每一条记录,一般都是前面一两个网页。
上面的截图我们可以看到,提交方式为POST,而POST的对象是这个网页http://myportal.sit.edu.cn/userPasswordValidate.portal
并不是我们的输入账号密码的主页,这里很重要,POST的网页不能弄错了。、
下面POST Data中,有4行数据的需要你post给网页的,提交代码可以这样写
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("goto", "http://myportal.sit.edu.cn/loginSuccess.portal")
.add("gotoOnFail", "http://myportal.sit.edu.cn/loginFailure.portal")
.add("Login.Token1",username.getText().toString())
.add("Login.Token2",password.getText().toString())
.build();
Request request1 = new Request.Builder()
.url("http://myportal.sit.edu.cn/userPasswordValidate.portal")
.post(requestBody)
.build();
requestBody是提交的数据,request是提交请求,后面还回有response,就是网页返回的数据。
接下来我们继续看httpwatch抓包的内容
我们post的网页返回的header(头文件信息),头文件包含了COOKIE,但是这个cookie并不是我们想要的。
看写一个网页:
我们看到下面有个网页和登录页面网址一样的
在第一个网页登录成功后,会返回一个才cookie信息,这个cookie需要和头文件信息一起提交给第二个网页
get提交头文件信息代码:
Request request = new Request.Builder()
.url(LOGINURL2)
.header("Accept", "text/html, application/xhtml+xml, image/jxr, */*")
// .header("Accept-Encoding", "gzip, deflate")
//这样可以注释掉,不注释的话返回数据乱码
.header("Accept-Language", "zh-Hans-CN,zh-Hans;q=0.5")
.header("Connection", "Keep-Alive")
.header("Cookie", str)
.header("Host", "myportal.sit.edu.cn")
.header("Referer", "http://myportal.sit.edu.cn/userPasswordValidate.portal")
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko")
.build();
好了,最重要的就是获取cookie,然后将cookie和头文件信息提交就行了,然后网页会返回登录后的界面
看下我的结果图吧,我只是获取了网页数据,并没有进行分析,写的代码都很简单,(复杂的我也不会啊亲)
如果没有登录成功的话会返回登陆界面的数据。
二.实现代码
上面都是理论,下面开始码代码啦,都是看别人写的然后自己慢慢下,有奇怪的地方见谅哦。我将代码缩短了一些,只写了输入账号密码, 然后登录按钮
布局文件:
//用来显示返回的网页数据
开启线程进行网络操作:
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("goto", "http://myportal.sit.edu.cn/loginSuccess.portal")
.add("gotoOnFail", "http://myportal.sit.edu.cn/loginFailure.portal")
.add("Login.Token1",username.getText().toString())
.add("Login.Token2",password.getText().toString())
.build();
Request request1 = new Request.Builder()
.url(LOGINURL1)
.post(requestBody)
.build();
Response response1 = client.newCall(request1).execute();
final Headers headers = response1.headers();
// Log.d("头信息", "header " + headers);
HttpUrl loginUrl = request1.url();
// List cookies = Cookie.parseAll(loginUrl, headers); 这是另一种获取cookie的方法
cookies = headers.values("Set-Cookie");
Log.d("cookie信息", "onResponse-size: " + cookies);
if (cookies != null) {
save(cookies);
//保存cookies,不知道可不可行
}
//List是String数组集合,先转换成String[],在转换成String
String[] strs = cookies.toArray(new String[cookies.size()]);
String str = null;
for (int i = 0; i < strs.length; ++i) {
str = strs[i];
}
Request request = new Request.Builder()
.url(LOGINURL2)
.header("Accept", "text/html, application/xhtml+xml, image/jxr, */*")
// .header("Accept-Encoding", "gzip, deflate")
//这样可以注释掉,不注释的话返回数据乱码
.header("Accept-Language", "zh-Hans-CN,zh-Hans;q=0.5")
.header("Connection", "Keep-Alive")
.header("Cookie", str)
.header("Host", "myportal.sit.edu.cn")
.header("Referer", "http://myportal.sit.edu.cn/userPasswordValidate.portal")
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
showResponse(responseData);
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
// Log.d("源代码", "onResponse: " + response.body().string().toString());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
需要注意的是如何从response获取cookie,然后将List
Response response1 = client.newCall(request1).execute();
final Headers headers = response1.headers();
// Log.d("头信息", "header " + headers);
HttpUrl loginUrl = request1.url();
// List cookies = Cookie.parseAll(loginUrl, headers); 这是另一种获取cookie的方法
cookies = headers.values("Set-Cookie");
Log.d("cookie信息", "onResponse-size: " + cookies);
if (cookies != null) {
save(cookies);
//保存cookies,不知道可不可行
}
//List是String数组集合,先转换成String[],在转换成String
String[] strs = cookies.toArray(new String[cookies.size()]);
String str = null;
for (int i = 0; i < strs.length; ++i) {
str = strs[i];
}
完整的代码就不放出来来了,可以在下面下载。
https://download.csdn.net/download/qq_36332133/10424800放下自己的QQandroid学习交流群:698691129