httpclient使用詳解(爬蟲)
一、簡介
HttpClient是Apache Jakarta Common下的子專案,用來提供高效的、最新的、功能豐富的支援HTTP協議的客戶端程式設計工具包,並且它支援HTTP協議最新的版本和建議。HttpClient已經應用在很多的專案中,比如Apache Jakarta上很著名的另外兩個開源專案Cactus和HTMLUnit都使用了HttpClient。
二、特性
1. 基於標準、純淨的Java語言。實現了Http1.0和Http1.1
2. 以可擴充套件的面向物件的結構實現了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。
3. 支援HTTPS協議。
4. 通過Http代理建立透明的連線。
5. 利用CONNECT方法通過Http代理建立隧道的https連線。
6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認證方案。
7. 外掛式的自定義認證方案。
8. 便攜可靠的套接字工廠使它更容易的使用第三方解決方案。
9. 連線管理器支援多執行緒應用。支援設定最大連線數,同時支援設定每個主機的最大連線數,發現並關閉過期的連線。
10. 自動處理Set-Cookie中的Cookie。
11. 外掛式的自定義Cookie策略。
12. Request的輸出流可以避免流中內容直接緩衝到
13. Response的輸入流可以有效的從socket伺服器直接讀取相應內容。
14. 在http1.0和http1.1中利用KeepAlive保持持久連線。
15. 直接獲取伺服器傳送的response code和 headers。
16. 設定連線超時的能力。
17. 實驗性的支援http1.1 response caching。
18. 原始碼基於Apache License 可免費獲取。
三、使用方法
使用HttpClient傳送請求、接收響應很簡單,一般需要如下幾步即可。
1. 建立HttpClient物件。
2. 建立請求方法的例項,並指定請求URL。如果需要傳送GET請求,建立HttpGet物件;如果需要傳送POST請求,建立HttpPost物件。
3. 如果需要傳送請求引數,可呼叫HttpGet、HttpPost共同的setParams(HetpParams params)方法來新增請求引數;對於HttpPost物件而言,也可呼叫setEntity(HttpEntity entity)方法來設定請求引數。
4. 呼叫HttpClient物件的execute(HttpUriRequest request)傳送請求,該方法返回一個HttpResponse。
5. 呼叫HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取伺服器的響應頭;呼叫HttpResponse的getEntity()方法可獲取HttpEntity物件,該物件包裝了伺服器的響應內容。程式可通過該物件獲取伺服器的響應內容。
6. 釋放連線。無論執行方法是否成功,都必須釋放連線
四、樣例
HttpClientRequestHandler類- package com.xiaojiang.httpclient;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.net.MalformedURLException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.zip.GZIPInputStream;
- import org.apache.commons.io.IOUtils;
- import org.apache.http.Header;
- import org.apache.http.HttpResponse;
- import org.apache.http.NameValuePair;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.util.EntityUtils;
- import org.jsoup.Jsoup;
- import org.jsoup.nodes.Document;
- import com.xiaojiang.exception.DataTaskException;
- publicclass HttpClientRequestHandler {
- privatestaticfinalint ERROR_CODE = 1;
- /**
- * get方式提交資料
- */
- publicstatic Document doGet(String url, String proxyIp, Integer proxyPort) throws DataTaskException{
- //System.out.println("doGet中使用代理:"+proxyIp+":"+proxyPort);
- HttpClient client = HttpConnectionManager.getHttpClient(proxyIp, proxyPort);
- HttpGet httpGet = new HttpGet(url);
- httpGet.setHeader("Accept-Language", "zh-cn,zh;q=0.5");
- httpGet.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");
- httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
- httpGet.setHeader("Accept-Encoding", "gzip, deflate");
- httpGet.setHeader("User-Agent", HttpUserAgent.get());
- try{
- //執行
- HttpResponse response = client.execute(httpGet);
- int statuCode = response.getStatusLine().getStatusCode();
- if(statuCode == 200){
- String html = formatResponse(response);
- if(html != null){
- return Jsoup.parse(html);
- }
- returnnull;
- } else {
- thrownew DataTaskException(statuCode, "請求URL【"+url+"】,"+statuCode+"錯誤", null);
- }
- } catch (Exception e){
- thrownew DataTaskException(ERROR_CODE, e.getMessage(), e);
- } finally {
- if(httpGet != null){
- httpGet.abort();
- }
- }
- }
- /**
- * post方式提交
- * @throws DataTaskException
- */
- publicstatic Document doPost(String url, Map<String,String> paramaters, String proxyIp, Integer proxyPort) throws DataTaskException{
- HttpClient client = HttpConnectionManager.getHttpClient(proxyIp, proxyPort);
- HttpPost request = new HttpPost(url);
- request.setHeader("Accept", "application/json, text/javascript, */*; q=0.01");
- request.setHeader("Accept-Encoding", "gzip, deflate");
- request.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
- request.setHeader("Cache-Control", "no-cache");
- request.setHeader("Connection", "keep-alive");
- request.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
- // 建立名/值組列表
- List<NameValuePair> parameters = new ArrayList<NameValuePair>();
- for(String key : paramaters.keySet()){
- parameters.add(new BasicNameValuePair(key, paramaters.get(key)));
- }
- try {
- // 建立UrlEncodedFormEntity物件
- UrlEncodedFormEntity formEntiry = new UrlEncodedFormEntity(parameters);
- request.setEntity(formEntiry);
- // 執行請求
- HttpResponse response = client.execute(request);
- int statuCode = response.getStatusLine().getStatusCode();
- if (statuCode == 200) {
- String html = formatResponse(response);
- if(html != null){
- return Jsoup.parse(html);
- }
- returnnull;
- } elseif (statuCode == 404) {
- thrownew DataTaskException(ERROR_CODE, "請求URL