httpclient模拟登录上海交大jaccount

前言

  之前写过一篇博客是用python的urllib库来模拟登录jaccount。后来想要做一个APP,其中一个模块需要登录jaccount,于是想要用java来实现同样的功能。这次采用的是httpclient 4.5,可以自行从官网下载并添加到自己的工程中。

注意

  1. httpclient 4.5可以自动管理cookie。也就是说在工程中如果使用同一个httpclient多次访问网页,那么它会自动携带服务器返回的cookie信息。
  2. 这是我走过最大的一个弯路,httpclient 的GET请求方式可以自动进行重定向(当服务器返回302时自动进行处理),但是httpclient的POST方式则不会。python的urllib库的GET和POST方式都自动重定向,在这个地方卡了很长时间。解决方法有两种,一是手动处理,二是采用工具,HttpClientBuilder builder = HttpClients.custom()
    .disableAutomaticRetries() //关闭自动处理重定向
    .setRedirectStrategy(new LaxRedirectStrategy());//利用LaxRedirectStrategy处理POST重定向问题
  3. httpclient的请求地址都要加上“http://”否则会返回错误信息。

源代码

public class Jaccount {

    private static String captchaUrl = "https://jaccount.sjtu.edu.cn/jaccount/captcha";
    private static String loginUrl = "http://electsys.sjtu.edu.cn/edu/login.aspx";
    private static String postUrl = "https://jaccount.sjtu.edu.cn/jaccount/ulogin";
    private static String openUrl = "http://electsys.sjtu.edu.cn/edu/student/examArrange/examArrange.aspx";
    private static RequestConfig config = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
    private static CookieStore cookieStore = new BasicCookieStore();
    private static HttpClientContext context = HttpClientContext.create();
    private static CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(config)
            .setDefaultCookieStore(cookieStore).build();

    public static void login() {
        String sid = "";
        String returl = "";
        String se = "";
        String v = "";
        String captcha = "";
        context.setCookieStore(cookieStore);
        String responseBody = getHtml(loginUrl);
        captcha = getCaptcha();

        Pattern r = Pattern.compile("name=\"sid\" value=\"(.+?)\">");
        Matcher matcher = r.matcher(responseBody);
        while (matcher.find())
            sid = matcher.group(1);
        r = Pattern.compile("name=\"returl\" value=\"(.+?)\">");
        matcher = r.matcher(responseBody);
        while (matcher.find())
            returl = matcher.group(1);
        r = Pattern.compile("name=\"se\" value=\"(.+?)\">");
        matcher = r.matcher(responseBody);
        while (matcher.find())
            se = matcher.group(1);
        r = Pattern.compile("name=\"v\" value=\"(.+?)\">");
        matcher = r.matcher(responseBody);
        while (matcher.find())
            v = matcher.group(1);
        // System.out.println("se " + se);
        // System.out.println("returl " + returl);
        // System.out.println("sid " + sid);
        // System.out.println("v " + v);

        List<NameValuePair> list = new ArrayList<NameValuePair>();
        list.add(new BasicNameValuePair("sid", sid));
        list.add(new BasicNameValuePair("returl", returl));
        list.add(new BasicNameValuePair("se", se));
        list.add(new BasicNameValuePair("v", v));
        list.add(new BasicNameValuePair("user", "......"));
        list.add(new BasicNameValuePair("pass", "......"));
        list.add(new BasicNameValuePair("captcha", captcha));

        HttpPost httpPost = new HttpPost(postUrl);
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(list, Consts.UTF_8));
            CloseableHttpResponse response = httpClient.execute(httpPost, context);

            
            // System.out.println("POST Response Status:: " +
             response.getStatusLine().getStatusCode());
            //这里会返回302,所以用GET方式,进行重定向操作
            String locationUrl = response.getLastHeader("Location").getValue();
            // System.out.println("POST Response Location:: " + locationUrl);
            getHtml("http://jaccount.sjtu.edu.cn" + locationUrl);
            // System.out.println("POST Response Status:: " +
            // response.getStatusLine().getStatusCode());
            // locationUrl = response.getLastHeader("Location").getValue();
            // System.out.println("POST Response Location:: " + locationUrl);
            
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, "utf-8");

            System.out.println(result);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static String getCaptcha() {
        String captcha = "";

        File file = new File("captcha.jpg");
        if (file.exists())
            file.delete();
        InputStream input = null;
        FileOutputStream out = null;
        try {
            HttpGet httpGet = new HttpGet(captchaUrl);
            CloseableHttpResponse response = httpClient.execute(httpGet, context);
            HttpEntity entity = response.getEntity();
            input = entity.getContent();
            int i = -1;
            byte[] by = new byte[1024];
            out = new FileOutputStream(file);
            while ((i = input.read(by)) != -1)
                out.write(by);
            input.close();
            out.close();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedOperationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.print("input the captch: ");
        Scanner scan = new Scanner(System.in);
        captcha = scan.nextLine();
        scan.close();

        return captcha;
    }

    public static String getHtml(String url) {
        HttpGet httpget = new HttpGet(url);
        // Create a response handler
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        String responseBody = "";
        try {
            responseBody = httpClient.execute(httpget, responseHandler, context);
        } catch (Exception e) {
            e.printStackTrace();
            responseBody = null;
        } finally {
            httpget.abort();
        }
        return responseBody;
    }

    public static void main(String[] args) {
        login();
        //访问考试安排界面测试是否登录成功
        System.out.println(getHtml(openUrl));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值