[置顶] 针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(一)
2016-08-30 22:53
761 查看
针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(一)
2016年8月31日00:03:40本人android新手,就读于安阳师范学院,最近在做教务系统登陆的案例,也是在拜读了网上很多做过类似案例的博客,发表一下自己的一点见解。
【0】使用了相关类 HttpClient Jsoup(jsoup这个需要自己下载jar包)
【1】我使用的是 火狐浏览器的 firebug 工具进行的抓包(在火狐的插件里可以下载)
抓包过程演示
{1} 先找到我们需要在android 端模拟登陆的教务系统网站,我这里先使用一个类似教务系统网站的网站,(是我们学校的一个网络学习中心)来实现模拟登陆,原理都是一样的,并无差别。
打开火狐浏览器的firebug 工具
找到登陆界面,填写我们的账号 和 密码
(注意事项:在firebug界面的 ”保持“ 选项要选中,这样才能看懂到 post请求)
登陆成功后,我们来看第一条,标识有 post 状态 为(302 或者 200)
在这个里面 分别有 头信息 , post 数据,cookies 这三个是比较重要的,
头信息中可以知道
Cookie JSESSIONID=3478af40-368a-4f91-a467-01ec789f1fd2.Test01 (这个主要用于标识我们的身份,就是让服务器知道你是 张三,而不是李四,这个很重要。)
Referer
Referer http://202.196.240.54/portal/relogin (这个就是我们需要在android 端使用到的进行post登陆网址)
下面来看 post 的相关数据项(我把密码涂掉了)
这个是很简单的没有太多参数
eid 对应就是 账号
pw 对应就是 密码
submit 对应是登陆(这只是个参数,没有卵用,而且它需要 url编码 ,可以看见在下面的 源代码中 是这样的:%E7%99%BB++%E5%BD%95 到时候在代码中实现 是这样的 : URLEncoder.encode(“登陆”, “gbk”))
这些数据项我们都要用到,至少针对这个 post 是这样的,但是有些数据项会很多,在android 模拟登陆的时候我还不太清楚是不是有些不用提交。
来看 cookies 说白了就是我们在 头信息中 cookie(3478af40-368a-4f91-a467-01ec789f1fd2.Test01 ) 的值,我就不上图了
【分割线[b]***********************************************************[/b]
针对上面的post 中数据项少,我把正常情况的数据项贴出来,并并做出一些解释和我想询问的问题:
这个 是我们学校教务系统登陆后的 post 数据项
在这里我解释一下我怎么没用我们学校的教务系统来写这个.
我们学校使用的教务系统是青果的,我在分析这个 post数据项的时候 ,发现
txt_pewerwedsdfsdff
txt_sdertfgsadscxcadsads
这两个都是空值,这两个我看过网页源码 一个是 密码 一个是 验证码,可是为什么是空值,答案就在 上面的这两个参数
dsdsdsdsdxcxdfgfg
fgfggfdgtyuuyyuuckjg
第一个是密码,第二个是验证码,这个是因为它进行了 md5 加密,将密码 和 验证码 加密了,而且我在看网页源码的时候,找到了 加密过程 和 加密算法,
unction chkpwd(obj) // 加密密码的 { if(obj.value!='') { var s=md5(document.all.txt_asmcdefsddsd.value+md5(obj.value).substring(0,30).toUpperCase()+'10479').substring(0,30).toUpperCase(); document.all.dsdsdsdsdxcxdfgfg.value=s;} else { document.all.dsdsdsdsdxcxdfgfg.value=obj.value;} } // 加密验证码的 function chkyzm(obj) { if(obj.value!='') { var s=md5(md5(obj.value.toUpperCase()).substring(0,30).toUpperCase()+'10479').substring(0,30).toUpperCase(); document.all.fgfggfdgtyuuyyuuckjg.value=s;} else { document.all.fgfggfdgtyuuyyuuckjg.value=obj.value.toUpperCase();}}//--> </script>
//加密算法,贴出来一部分 unction md5js(pass, code, uin) { var I = hexchar2bin(md5(pass)); var H = md5(I + uin); var G = md5(H + code.toUpperCase()); return G } var hexcase = 1; var b64pad = ""; var chrsz = 8; var mode = 32; function md5(A) { return hex_md5(A) } function hex_md5(A) { return binl2hex(core_md5(str2binl(A), A.length * chrsz)) } function str_md5(A) { return binl2str(core_md5(str2binl(A), A.length * chrsz)) } function hex_hmac_md5(A, B) { return binl2hex(core_hmac_md5(A, B)) }
所以我在android 实现登陆我们学校的教务系统的时候,就出现了问题,因为我在发送参数的 只能发送 post 请求那样写的 参数,所以我自己要将加密过程实现,或者还有其它的方法,但我没想到。
出现这个好像是只要在 青果的教务系统 上, 正方的教务系统 应该是没有加密。
如果那位大神知道怎么弄,需要可以解决一下。
分割线[b]***********************************************[/b]】
好了,我们言归正传,对登陆过程的抓包,基本就是这些了。
下面我们将利用到我们得到的东西,在android 端实现这个过程,我们先明确一下过程.
【0】写好我们的登陆界面,并加上网络访问权限
【1】拿到我们需要登陆的网址 http://202.196.240.54/portal/relogin
【2】使用 HttpClient 相关类来 实现登陆过程
【3】设置我们需要参数 (post的数据项)
【4】判断访问是否成功 (==200)
【5】拿到返回的 cookies
【6】拿到响应的网页源码,并且使用 jsoup 解析,这样就拿到我们需要的信息。
【7】将获取的信息,在控件上显示出来。
代码展示 :
【0】登陆界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.aynu.dengluanli.MainActivity" > <TextView android:id="@+id/id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号" /> <EditText android:id="@+id/id_ed" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/pwd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码" /> <EditText android:id="@+id/pwd_ed" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/tijiao" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="登陆" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/id_text_infor" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="144803085" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/name_text_infor" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="***" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/sj_text_infor" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2016年8月30日" android:textSize="20sp" /> </LinearLayout> </LinearLayout>
下面的三个 textview 等会我们会拿到我们的个人信息,然后更新上去。
网络访问权限 : android.permission.INTERNET (因为我们需要访问网络)
【1】登陆网站的过程 (其中有些我写有注解)
// 提交按钮的点击事件 public void onclick(View v) { new Thread(new Runnable() { // 耗时操作必须使用子线程 @Override public void run() { try { String un = username.getText().toString().trim(); // 获取填写的 用户名 String pwd = password.getText().toString().trim(); // 获取填写的 密码 // 【1】进行post 请求 使用httpclient client = new DefaultHttpClient();//【1.1】 实例化的httpclient 对象 // 【1.2】进行post请求 HttpPost httpPost = new HttpPost(postURL); // postURL 就是我们获得网址 // 【1.3】设置要进行 post请求的参数 List<NameValuePair> list = new ArrayList<NameValuePair>(); list.add(new BasicNameValuePair("eid", un)); list.add(new BasicNameValuePair("pw", pwd)); list.add(new BasicNameValuePair("submit", URLEncoder.encode("登陆", "gbk"))); // 上面出现的一个乱码部分,使用了url编码 // 提交表单信息 httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); // 响应请求 HttpResponse httpResponse = client.execute(httpPost); // 判断状态码 如果为 200 则要检查表单 如果为 302 继续 // //有的,其实我通过HttpWatch抓取的返回值就是302,只不过创建HttpClient时用的new // DefaultHttpClient() // 这个函数会直接跳转200,如果你用了DefaultHttpClient还是返回302的话,你可以 location // = response.getFirstHeader("Location").getValue() // location中有你想要的网址,然后再重新Post新网址就好 if (httpResponse.getStatusLine().getStatusCode() == 200) { // 获取 cookie cookies = client.getCookieStore().getCookies(); // 拿到的cookies 返回形式是 List<Cookie> HttpEntity entity = httpResponse.getEntity(); String main_html = EntityUtils.toString(entity); // 这个就是响应的网页源码 IsLoginSuccessful(main_html); // 这个方法是jsoup 解析的方法,可以先不看 } else { System.out.println(" 请求失败"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); }
在这里说一下我的一些看法,
(1)你获得到 cookie 后,可以跟 咱们之前在网站上 获取到的 cookie 进行对比,但是 会出现两种情况,一种是 cookie 整好比对上,并且每次都不会变化, 还有一种是 cookie 都会变化(当然这个是 账号 密码 都正确,不是账号密码不正确出现的),但是 这个不影响你的操作, 我还不清楚这个是怎么回事, 但是这个在你 携带 cookie 进行请求的时候,不会出现问题,你只需要将你拿到的 cookie 设置进去就行。
(1)你怎么才能知道你 登陆成功了么,在我们做的判断的地方
if (httpResponse.getStatusLine().getStatusCode() == 200) 这个只是请求是否成功的标志,并不是你登陆 是否成功的标志,你要查看你返回的 网页源码,通过看这个 你就知道你 是否登陆 成功了。
或者你通过 jsoup 看能不能 抓取到 关于登陆成功 出现的信息。 都是可以的。
演示:
登陆没有成功返回的源码(一部分)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="/library/skin/tool_base.css" type="text/css" rel="stylesheet" media="all" /> <link href="/library/skin/neo-bupt-blue/tool.css" type="text/css" rel="stylesheet" media="all" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <title>Sakai</title> <script type="text/javascript" src="/library/js/jquery/1.4.2/jquery-1.4.2.min.js"></script> <script type="text/javascript" language="JavaScript" src="/library/js/headscripts.js"></script> <meta name="viewport" content="width=device-width"/> </head> <body onload="if ((document.getElementById('pw').passwordfocus != true)) document.getElementById('eid' ).focus() ;parent.updCourier(doubleDeep, ignoreCourier);"> <script type="text/javascript" language="JavaScript"> focus_path = ["eid"]; </script> <!-- xlogin.vm --> <table class="login" cellpadding="0" cellspacing="0" border="0"> <tr> <th colspan="2">登 录</th> </tr> <tr> <td class="logo"></td> <td class="form"> <form method="post" action="http://202.196.240.54/portal/relogin" enctype="application/x-www-form-urlencoded" > <div class="alertMessage">登录信息不正确</div> <table border="0" class="loginform"> <tr> <td><label for="eid">用户名</label></td> <td><input name="eid" id="eid" value="144803085" type="text" size="15"/></td> </tr>
登陆成功返回的源码(一部分)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Language" content="zh-CN" /> <script type="text/javascript"> var portal = { "chat": { "enabled": false, "pollInterval": 5000, "video": {}, "translations": { "server_unavailable": "It looks like the chat server is unavailable. Check your network connection.", "server_error_send" : "Failed to send message. Reason: ", "server_error_send_error": "Error: " }, }, "loggedIn": true, "portalPath": "http://202.196.240.54/portal", "loggedOutUrl": "http://202.196.240.54/portal", "siteId": "~144803085", "siteTitle": "我的工作空间", "shortDescription": "", "locale": "zh-CN", "user": { "id": "144803085", "eid": "144803085" },
(3) 我们获取到的 cookie存放在 List 中,所以写一个方法,将 cookie的值读出来,方便我们在接下来 携带 cookie 请求时使用。
/** * 解析保存到的 cookies * @return cookies 值 */ public String parseCookie(){ // 判断cookies 是不是为空 if (cookies.isEmpty()) { System.out.println("cookies为空"); }else { // cookies 不为空,就从list中取出cookies 的value 值 for (int i = 0; i < cookies.size(); i++) { Cookie cookie = cookies.get(i); System.out.println(cookies.get(i).getName()+"===="+cookies.get(i).getValue()); cookies_value = cookies.get(i).getValue(); //拿到我们的 cookie 类型为 string } } return cookies_value; }
返回的结果 : 2474bce1-9ce1-4618-97de-dc861c48dcf6.Test01
这样基本上,登陆过程就结束了。
先写到这里,明天继续写。
相关文章推荐
- [置顶] 针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(二)
- Android实现模拟登陆教务系统并解析网页数据
- 网页抓取,模拟登陆,抓取动态网页内容等过程中,所涉及的Headers信息,Cookie信息,POST数据的处理逻辑
- Android模拟登陆综合教务系统客户端(java)-jsoup解析数据
- 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView
- Android入门:用HttpClient模拟HTTP的GET和POST请求
- C# : WebRequest发起Http Post请求模拟登陆并cookie处理示例
- Android Volley解析(一)之GET、POST请求篇
- Android Volley解析(一)之GET、POST请求篇
- Android入门:用HttpClient模拟HTTP的GET和POST请求
- Android 模拟登陆正方教务系统(一)
- Android模拟登陆校园教务系统
- Android 网页登录 POST 请求 保存 COOKIE
- Android 网页登录 POST 请求 保存 COOKIE
- java无需获取cookie实现模拟登陆正方教务系统获取课表等数据
- 【转】C# WebRequest发起Http Post请求模拟登陆并cookie处理示例
- Android Volley解析(一)之GET、POST请求篇
- 使用httpclient4.3.X模拟post请求登陆网站获取cookie信息的操作
- Android Volley解析(一)之GET、POST请求篇
- 【实战】(二)android模拟qq登录(apache的httpClient发送get和post请求)