工具介紹
本篇文章主要是解說怎樣模擬登陸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, List<NameValuePair> 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("獲取成功。。。。
。");
}
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;
}
