博主参加的学校的软件设计大赛,需要实现,模拟登陆本校的校园网,然后得到学生的成绩,这么一个功能。(类似超级课程表的那种)
看了看别人写的博客后终于弄明白是怎么回事了,在此记录下来以防忘记。
首先说明一下,博主使用的是Httpclient+Jsoup来实现的。
接下来,进入正题:
一,模拟登陆的原理:
假如用户已经输入了数据,当用户点击“登陆”按钮的时候,实际上就是一个form表单将数据提交到了服务器。
然后服务器在响应头部返回了cookie,我们需要的正是这个cookie。这就是我们登陆之后的通行证。也就是说,只要得到了它,我们就算是登陆成功了。
二,模拟登陆获取数据需要的条件:
1,账号
2,密码
3,可能存在的隐含参数(当用户点击“登陆”的时候,客户端可能会向服务器端发送一些除账号和密码以外的隐含参数。)
4,发送登陆请求的目的网址(URL)【这个网址会在我们发送请求之后,返回我们登陆后的通行证cookie】
5,发送获取数据请求的目的网址(URL)
三,思路:
1,利用浏览器中的开发者工具,找到二中的3、4、5条件。(这个第一次找可能比较慢,耐心点总会找到的)
2,将二中的1,2,3发送给4,得到cookie
3,利用第二步得到cookie去访问二中的5,就能得到数据了。
以上并没有说验证码的问题,如果有验证码的话,就将验证码下载到本地,然后让用户手动输入就解决了。
四,登陆代码的具体实现:
private static String login(String username,String password){ String urlGetCookie = ""; //发送账号密码的url String cookie = ""; try{ CloseableHttpClient client = HttpClients.createDefault();//构建一个Client HttpPost post = new HttpPost(urlGetCookie); //构建一个POST请求 //构建表单参数 List<NameValuePair> formParams = new ArrayList<NameValuePair>(); formParams.add(new BasicNameValuePair("Login.Token1", username)); formParams.add(new BasicNameValuePair("Login.Token2", password)); formParams.add(new BasicNameValuePair("captcha", "")); formParams.add(new BasicNameValuePair("goto", "")); formParams.add(new BasicNameValuePair("gotoOnFail", "")); //将表单参数转化为“实体 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8"); post.setEntity(entity); //将“实体“设置到POST请求里 HttpResponse response = client.execute(post); //提交POST请求 HttpEntity result = response.getEntity(); //拿到返回的HttpResponse的"实体" Header[] headers = response.getAllHeaders(); //得到响应头部 for(int i=0; i<headers.length;i++){ if(headers[i].getName().equals("Set-Cookie")){ cookie += headers[i].getValue(); //获得cookie } } String[] cookies = cookie.split("Path=/"); //将获得的cookie去掉“Path=/” client.close(); //关闭client return cookies[0]+cookies[1]; //返回cookie }catch (Exception e){ System.out.println("登陆代码出现异常"); e.printStackTrace(); } return null; }