本篇文章主要是讲解如何模拟登陆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的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, List nvps) {
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("获取成功。。。。。");
}
private boolean mockLogin() {
logger.info("开始登陆。。。。。");
boolean result = false;
List nvps = new ArrayList();
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;
}