//第一个URL,等着为后面服务public static final String login_url = "";//第一个Post模拟登陆的URLpublic static final String login_url2 = ""; HttpPost httpPost = new HttpPost(login_url2); //建立一个Post请求,第一步的方法是Post方法嘛//禁止重定向,由于刚刚Post的状态值是重定向,所以我们要去禁止它,不然网页会乱飞。 httpPost.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false); //设置头部信息(头部信息在刚刚的Httpwatch下面Headers标签会有,不过我感觉写多跟写少没多大区别,只是多写没有坏处吧。)httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko"); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded");//第一种模拟登陆传值List<NameValuePair> params = new ArrayList<NameValuePair>();//将刚刚获取到的值添加到List的中params.add(new BasicNameValuePair("__VIEWSTATE","dDwtMTIwMTU3OTE3Nzs7PsvpgBGP9UryEzGkfCRBEu734TJ/"));//params.add(new BasicNameValuePair("__VIEWSTATE", "/wEPDwUJNDcyMzA1MjkxZGRTx3lVi2lf6h+y/PVVH1qMZzouJg=="));//params.add(new BasicNameValuePair("__EVENTVALIDATION", "/wEWCwLkl9v4DwLs0bLrBgLs0fbZDAK/wuqQDgKAqenNDQLN7c0VAuaMg+INAveMotMNAoznisYGArursYYIAt+RzN8IIdJ+D2D5xaddz6rv7AABSyHhO14="));params.add(new BasicNameValuePair("TextBox1", "1205107009"));// 账号params.add(new BasicNameValuePair("TextBox2", "*********"));// 密码(密码先保密吧。需要的话私聊)params.add(new BasicNameValuePair("RadioButtonList1", "%D1%A7%C9%FA"));// 学生params.add(new BasicNameValuePair("Button1", ""));params.add(new BasicNameValuePair("lbLanguage", ""));
这样的话就把要模拟登陆的所有Post参数全部放到这个List当中了。大家看看在params.add值的时候有没有注意到我把其中的两行给注释掉了?还记得刚刚我记的绿色的标记不?这里我给大家解释一下,由于我们学校教务返回参数的时候会两种不同的情况,就是有时候是只但会一个__VIEWSTATE的值,有时候返回__VIEWSTATE和__EVENTVALIDATION这两个值,而且两个__VIEWSTATE还不一样,,这是我用HttpWatch观察到的,不知道你们学校的教务会不会出现这中情况,你们自己注意一下。这里我就直接使用第一种只传递__VIEWSTATE的值给大家做例子,另外一种情况我都注释在第一种情况的下行代码。ps:有的学校没有这种情况,而且居然不要验证码直接就能进入教务主页,比如像南邮。好,贴完刚刚将值加入List的代码,现在我们开始进行模拟登陆了。
try {// 传递参数的时候注意编码使用,否则乱码httpPost.setEntity(new UrlEncodedFormEntity(params, "GBK")); //响应请求 HttpResponse response = client.execute(httpPost); //获取响应状态码 int Status = response.getStatusLine().getStatusCode(); //302表示重定向状态 if(Status == 302||Status == 301){//获取响应的cookie值cookie = response.getFirstHeader("Set-Cookie").getValue();//获取头部信息中Location的值location = response.getFirstHeader("Location").getValue();}}这一步是设置下Post值的编码方式,然后进行响应请求获取返回的信息。响应的状态码为302,刚刚已经在HttpWatch中看到了。那个这个时候重定向到哪里了呢,这个时候我们发现在Post下面的Get方式,通过Get方式访问的URL是?xh=1205107009,是一个带着查询字符串的URL,那么这个URL怎么获取呢。
这里我来解释一下,重定向后的信息都储存在头部信息中。如下图:
不然看出location的值就是主页地址的结尾部分。
这个时候的mianUrl =login_url + location即为?xh=1205107009,然后下一步是Get请求,状态码是200。这样就好做多了,不是吗?
HttpGet get = new HttpGet(mianUrl);//关键点,这里有个关键点就是设置头部信息中的Referer和cookie值,cookie值大家都知道,模拟登陆的时候必须带着cookie一起访问,但是Referer我无法理解,但必须要设置。//也就是必须指定它的Referer必须为当前访问的URLget.setHeader("Referer", mianUrl);get.addHeader("Cookie", cookie);try {//获取Get响应,如果状态码是200的话表示连接成功HttpResponse httpResponse = new DefaultHttpClient().execute(get);if(httpResponse.getStatusLine().getStatusCode() == 200){HttpEntity entity = httpResponse.getEntity();//获取纯净的主页HTML源码,这里大家可以将mianhtml定义在其他地方String mainhtml = EntityUtils.toString(entity);}到这里呢,基本上就等于完事了,获取到主页的HTML纯文本之后就是通过Jsoup包进行解析了,不会使用的话可以去查下它的API文档。
第二步:
下面我们就开始查询我们的成绩的了,首先呢还是HttpWatch工具,依次点击信息查询中的成绩查询,然后点击按学期查询就会查询到在校所有成绩了。
这里我们依然会发现因为是按了按钮,所以传递了值,所以还是Post请求,不是状态码是 200。
Post的URL是?xh=1205107009&xm=陈凯&gnmkdm=N121605
追寻爱情,然后发现,爱,从来就是一件千回百转的事。