标签:
不同学校的教务系统设计应该会有不同,这里就只针对我的学校。本文主要讲作为纯小白连返回码302都还不懂的我是怎么一步步整的。
我打算用的是java。
因为模拟登录这块以前都没做过,就简单百度了下,找到了开发用的相应的包,比如httpclient,网上也有别人做好的代码上传的,所以就先跑跑别人的代码试试呗,记住把需要的jar包先下好并导入到工程,下面是别人的代码
package com.zb.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.AbstractHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.http.cookie.Cookie; public class postData { HttpResponse httpResponse; List<Cookie> cookies; String result = ""; String data = ""; public void getResult() { String url = "http://210.38.137.101:9080/xsxt/xsxt.jsp";// 海大 HttpClient httpclient = new DefaultHttpClient(); /* 建立HTTP Post连线 */ HttpPost httpPost = new HttpPost(url); List<NameValuePair> params = new ArrayList<NameValuePair>(); // 用户名密码 params.add(new BasicNameValuePair("userId", "xxxx")); params.add(new BasicNameValuePair("userPass", "xxx")); // 发出http request try { // 发出HTTP request /* 添加到httpPost提交的内容中 */ httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); // 执行 ,取得HTTPresponse httpResponse = httpclient.execute(httpPost); // 若状态码为200 ok if (httpResponse.getStatusLine().getStatusCode() == 200) { // 返回值正常 // 获取返回的cookie cookies = ((AbstractHttpClient) httpclient).getCookieStore() .getCookies(); } /*String timestatus = "201011311229" + new SimpleDateFormat("MMddHHmmss").format(new Date());*/ // String kbURL = "http://210.38.137.101/pls/wwwbks/xk.CourseView"; // // 查看HttpWatch里相应的URL String cjURL = "http://210.38.137.101/pls/wwwbks/bkscjcx.yxkc"; /* 建立HttpGet联机 */ HttpGet httpGet = new HttpGet(cjURL); httpGet.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue()); httpGet.setHeader("Referer", "http://210.38.137.101:9080/xsxt/left.jsp"); // httpResponse.setHeader("User-Agent", // "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"); HttpResponse response2 = new DefaultHttpClient().execute(httpGet); /* 若状态码为200 ok */ System.out.println("status=" + response2.getStatusLine().getStatusCode()); if (response2.getStatusLine().getStatusCode() == 200) { StringBuffer sb = new StringBuffer(); // 获取响应实体 HttpEntity entity = response2.getEntity(); InputStream is = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader( is, "GB2312")); // 是读取要改编码的源,源的格式是GB2312的,安源格式读进来,然后再对源码转换成想要的编码就行 while ((data = br.readLine()) != null) { sb.append(data); } result = sb.toString(); // 此时result中就是我们成绩的HTML的源代码了 } } catch (Exception e) { e.printStackTrace(); } // HttpClient httpclient2 = new DefaultHttpClient(); System.out.println(data); System.out.println(result); } public static void main(String[] args) { postData pd = new postData(); // pd.postData(); pd.getResult(); } }
毕竟目前小白,自然地,哪有那么容易就成功的,于是乎就开始了漫长的找问题和解决问题的过程,中间还停了挺长一段时间,没办法课多别的事多,毕竟这个只是一个课余的一个想法。我用的抓包工具是火狐下的httpfox,本想用httpwatch,可火狐上用不了,因为下的是basic版,ie竟然也用不了,老提示升级成profession版,暂时没兴趣,就凑活用先,个人觉得新手的关注点不是工具。
废话说的有点多了。。。我就登信息系统,就看post了什么数据过去,没错,就是只有stuid,pwd,
那不应该啊,看着别人的代码好像是对的样子,不过有些地方还是有疑问的,比如这句:httpGet.setHeader("Cookie", "JSESSIONID="+ cookies.get(0).getValue());初次运行就是这报错的,什么空指针异常的,不懂乍回事唉。。。折腾了好久,抓的包一条条的看,看各个地址,并不断在原有代码上各种调整,比如把上面这句删掉了后,就跑起来了,但获取的页面文本是,请输入账号密码之类就是根本就没登录上的意思。仔细看代码可以知道是分成两步的,前面是最开始的登录,后面跑去成绩的页面。既然登都没登上,那就先主攻登录这块,可是该post的都post啦,咋回事,当时也不懂cookies这东西,就在想是不是他的为题,经过各种百度,cookies是向服务端发出请求后服务端返回给客户端也就是浏览器的一个标识,这样你在登录后的操作就只需亮出你的cookies证明你已经登录过了,可以继续逛。那么就不该是cookies的问题了。刚刚突发奇想试了下post地址换成网页登录页面的,竟然失败了,要知道中间停下来不做前好像一直用的是他啊,晕!所以提醒大家,抓包仔细看看post到哪个地址,并不是你在哪个页面地址登录,就post到那,以我学校为例,抓包后明显登录页面是由几个模块组合起来。。还是不行,那么哪出事了,在百度过程我看到了重定向这个概念,也就是服务端返回了302,巧了,好像抓包时有,还有我发现在Post那条中的Query String里有值
多次试验是动态的,会不会和他们有关,在抓到的包中也发现了一个与此相关的js文件,里面是几个函数,看起来就是和他的value值有关,还有抓包查看了post的地址,就是在原来的基础上加上了jym2005=value,这时我还以为这就是重定向的地址.......如果搞到他再get就好了,理想总是丰满,于是乎就开始研究怎么获取这个value,可弄了好久也没结果,百度到的query String的东西都搞不懂是啥或者和这个有关系,我还百度怎么直接获取重定向后的地址,试了网上的各种方法,没啥基础,只能照着试呗,不能实现也不会改,但还是找到了一个可以用的httpResponse.getLastHeader("Location").getValue(); 我把它获取的东西打印了出来,发现根本就不是什么jym的,而是这个东西login2.loginmessage,天,这差的太远了,然后就又一阵瞎搞,都无果而终,要是仔细点注意到上面右图的第二条的地址就省很多时间了,login2.loginmessage不就是get的那个url,重定向本就是post后再get的,因为我之前试过直接用那第二条的url在浏览器打开,结果是空白。。。没错绕了一圈用还是用httpResponse.getLastHeader("Location").getValue();完整的试了下,竟然可以登上了,现在弄出来后,发现jym啥的和得到的login2.loginmessage这两者之间必定是存在某种联系的,后者不应该只是一个单纯的字符串,这可以后面研究研究,只要登录上了,那后面的查成绩看课表就好弄了,就不多说了,另外我获取cookies值得方式比较死板,若有好的方法感谢指教。
package test; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.AbstractHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.ExecutionContext; import java.util.ArrayList; import java.util.List; import org.apache.http.cookie.Cookie; public class test { HttpResponse httpResponse; List<Cookie> cookies; String result = ""; String cookie = ""; String data = ""; public void getResult() { String url = "http://";// HIT HttpClient httpclient = new DefaultHttpClient(); /* 建立HTTP Post连线 */ HttpPost httpPost = new HttpPost(url); List<NameValuePair> params = new ArrayList<NameValuePair>(); // 用户名密码 params.add(new BasicNameValuePair("stuid", "xxxx")); params.add(new BasicNameValuePair("pwd", "xxxx")); // 发出http request try { // 发出HTTP request /* 添加到httpPost提交的内容中 */ httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); // 执行 ,取得HTTPresponse httpResponse = httpclient.execute(httpPost); // 若状态码为302 重定向 if (httpResponse.getStatusLine().getStatusCode() == 302) { // 获取返回的cookie cookies = ((AbstractHttpClient) httpclient).getCookieStore().getCookies(); Header[] headers = httpResponse.getAllHeaders(); cookie=headers[4].getValue(); cookie=cookie.substring(0,27); //System.out.println(cookie); String locationUrl=httpResponse.getLastHeader("Location").getValue(); /* 建立HttpGet联机 */ HttpGet httpGet = new HttpGet("http://"+locationUrl); httpGet.setHeader("Cookie", cookie); HttpResponse response2 = new DefaultHttpClient().execute(httpGet); /* 若状态码为200 ok */ if (response2.getStatusLine().getStatusCode() == 200) { System.out.println("登录成功!"); HttpGet httpGet1 = new HttpGet("http://"); httpGet1.setHeader("Cookie", cookie); HttpResponse response3 = new DefaultHttpClient().execute(httpGet1); StringBuffer sb = new StringBuffer(); HttpEntity entity = response3.getEntity(); InputStream is = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "GB2312")); while ((data = br.readLine()) != null) {sb.append(data);} result = sb.toString(); // 此时result中就是我们成绩的HTML的源代码了 }else System.out.println("重定向跳转失败,登录失败!"); }else{ System.out.println("登陆失败!"); } } catch (Exception e) { e.printStackTrace(); } System.out.println(data); System.out.println(result); } public static void main(String[] args) { test pd = new test(); pd.getResult(); } }
用Apache httpclient模拟登陆学生个人信息系统
标签:
原文地址:http://blog.csdn.net/mrzzhou/article/details/51170036