工具介绍
本篇文章主要是解说怎样模拟登陆CSDN。使用的工具是HttpClient+Jsoup
当中HttpClient主要是负责发送请求,而Jsoup主要是解析HTML
你可能对HttpClient的API不太了解,只是没关系。往下看就好了~
Jsoup的语法类似jQuery的选择器。相信有一定web基础的人都能够非常快的掌握
当中select(String selector)就是最强大的选择器。另外还提供一系列的细化的方法,比方:
getElementById(String id), getElementsByClass(String class), getElementsByTag(String tagName)
是不是非常亲切?对~这个就跟javascript的方法类似了~
所以Jsoup对于开发WEB的朋友的学习成本是相当的低的!那么,继续吧骚年!
步骤分析
怎样简单高速使用HttpClient
可能你对HttpClient的API不熟悉。那么怎样在项目中高速使用HttpClient呢?
这里已经封装了两个最经常使用的get和post请求方法,所以之前就让你别操心啦~^_^
假设不想花时间看API的话直接拿去用就能够了
/** * Http工具类 * * @author Zhu * */public class HttpUtils { private static CloseableHttpClient httpClient = HttpClients.createDefault(); private static HttpClientContext context = new HttpClientContext(); private HttpUtils() { } public static String sendGet(String url) { CloseableHttpResponse response = null; String content = null; try { HttpGet get = new HttpGet(url); response = httpClient.execute(get, context); HttpEntity entity = response.getEntity(); content = EntityUtils.toString(entity); EntityUtils.consume(entity); return content; } catch (Exception e) { e.printStackTrace(); if (response != null) { try { response.close(); } catch (IOException e1) { e1.printStackTrace(); } } } return content; } public static String sendPost(String url, Listnvps) { CloseableHttpResponse response = null; String content = null; try { // HttpClient中的post请求包装类 HttpPost post = new HttpPost(url); // nvps是包装请求參数的list if (nvps != null) { post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); } // 运行请求用execute方法,content用来帮我们附带上额外信息 response = httpClient.execute(post, context); // 得到对应实体、包含响应头以及对应内容 HttpEntity entity = response.getEntity(); // 得到response的内容 content = EntityUtils.toString(entity); // 关闭输入流 EntityUtils.consume(entity); return content; } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return content; }}
如今get和post对你来说都已经轻而易举了。那么開始模拟登陆吧~
模拟登陆实战
/** * 获取必要的登陆參数信息 * * @throws IOException */ private void fetchNecessaryParam() throws IOException { // 查看CSDN登陆页面源代码发现登陆时须要post5个參数 // name、password,另外三个在页面的隐藏域中,a good start logger.info("获取必要的登陆信息。。。。。"); // 这样登陆不行,由于第一次须要訪问须要拿到上下文context // Document doc = Jsoup.connect(LOGIN_URL).get(); String html = HttpUtils.sendGet(LOGIN_URL); Document doc = Jsoup.parse(html); Element form = doc.select(".user-pass").get(0); lt = form.select("input[name=lt]").get(0).val(); execution = form.select("input[name=execution]").get(0).val(); _eventId = form.select("input[name=_eventId]").get(0).val(); logger.info("获取成功。。。
。
。"); }
2、用从1中得到的请求參数和账号password模拟发送post请求到登陆请求地址private boolean mockLogin() { logger.info("開始登陆。。
。
。。"); boolean result = false; List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("username", username)); nvps.add(new BasicNameValuePair("password", password)); nvps.add(new BasicNameValuePair("lt", lt)); nvps.add(new BasicNameValuePair("execution", execution)); nvps.add(new BasicNameValuePair("_eventId", _eventId)); String ret = HttpUtils.sendPost(LOGIN_URL, nvps); if (ret.indexOf("redirect_back") > -1) { logger.info("登陆成功。。。。
。"); result = true; } else if (ret.indexOf("登录太频繁") > -1) { logger.info("登录太频繁。请稍后再试。
。
。
。
。
"); } else { logger.info("登陆失败。。。。。"); } return result; }