HttpClient的爬取網頁原始碼

來源:互聯網
上載者:User
包UTIL;

進口java.io.BufferedReader中;
進口java.io.IOException異常;
進口的java.io.InputStream;
進口java.io.InputStreamReader中;
進口java.text.DateFormat中;
進口java.text.SimpleDateFormat的;
進口的java.util.ArrayList;
進口java.util.Date;
進口的java.util.HashMap;
進口的java.util.List;
進口的java.util.Map;
進口java.util.Set中;
進口java.util.Map.Entry;
進口java.util.zip.GZIPInputStream;

進口org.apache.commons.httpclient.Header;
進口org.apache.commons.httpclient.HttpClient;
進口org.apache.commons.httpclient.HttpException;
進口org.apache.commons.httpclient.HttpMethod;
進口org.apache.commons.httpclient.HttpStatus;
進口org.apache.commons.httpclient.NameValuePair;
進口org.apache.commons.httpclient.SimpleHttpConnectionManager;
進口org.apache.commons.httpclient.methods.GetMethod;
進口org.apache.commons.httpclient.methods.PostMethod;
進口org.apache.commons.httpclient.params.HttpConnectionManagerParams;
進口org.apache.commons.httpclient.params.HttpMethodParams;

/ **
* @author六味
*日期:2009年12月18日
*
* TODO
* HttpClient的輔助類
* /
public類HttpClientHelper
{

/ **
* HttpClient的連線逾時,讀取資料逾時時間設定(單位:毫秒)
* /
公用靜態最終詮釋HTTPCLIENT_CONNECTION_TIMEOUT = 30000;
公用靜態最終詮釋HTTPCLIENT_SO_TIMEOUT = 120000;
公用靜態最終詮釋HTTPMETHOD_SO_TIMEOUT = 5000;

//讓的ConnectionManager管理httpclientconnection時是否關閉串連
私人靜態布爾alwaysClose = FALSE;
私人靜態字串defaultEncode =“UTF-8”;

私人靜態最後的DateFormat DATE_FORMAT =新的SimpleDateFormat(“YYYY-MM-DD HH:MM:SS”);

/ **
*擷取HttpClient的串連,並設定相關參數
*
* @return
* /
公用靜態HttpClient的getHttpClient()
{
HttpClient的用戶端=新的HttpClient(新SimpleHttpConnectionManager(alwaysClose));
HttpConnectionManagerParams managerParams = client.getHttpConnectionManager()getParams()方法。
//設定連線逾時時間(單位毫秒)
managerParams.setConnectionTimeout(HTTPCLIENT_CONNECTION_TIMEOUT);
//設定讀資料逾時時間(單位毫秒)
managerParams.setSoTimeout(HTTPCLIENT_SO_TIMEOUT);
返回用戶端;
}

/ **
*擷取HttpClient的串連,並設定相關參數
*
* @參數logonSite
* @參數logonPort
* @參數協議
* @return
* /
公用靜態HttpClient的getHttpClient(最後弦樂logonSite,最終詮釋logonPort,最後弦樂協議)
{
HttpClient的用戶端=新的HttpClient(新SimpleHttpConnectionManager(alwaysClose));
client.getHostConfiguration()setHost(logonSite,logonPort,協議)。
HttpConnectionManagerParams managerParams = client.getHttpConnectionManager()getParams()方法。
//設定連線逾時時間(單位毫秒)
managerParams.setConnectionTimeout(HTTPCLIENT_CONNECTION_TIMEOUT);
//設定讀資料逾時時間(單位毫秒)
managerParams.setSoTimeout(HTTPCLIENT_SO_TIMEOUT);
返回用戶端;
}

私人靜態列表<標題> getHeaders(地圖<String,字串>頭)
{
名單<標題> =前序的ArrayList新<標題>();
布爾includeUserAgent = FALSE;
如果(空=頭&&假== header.isEmpty()!)
{
集<進入<字串,字串>> =的entrySet header.entrySet();
對於(進入<String,字串>項:的entrySet)
{
如果(假== includeUserAgent
&&“使用者代理程式”.equals(entry.getKey()))
{
includeUserAgent = TRUE;
}
headers.add(新前序(entry.getKey(),entry.getValue()));
}
}

如果(假== includeUserAgent)
{
headers.add(新標題(
“使用者代理程式”,
“Mozilla的/ 4.0(相容; MSIE 7.0; Windows NT的5.1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0 0.50727; Alexa工具條; MAXTHON 2.0)“));
}
返回頭;
}

私人靜態NameValuePair [] getPairs(地圖<String,字串> POSTDATA)
{
如果(空== || POSTDATA postData.isEmpty())
{
返回NULL;
}

設定<輸入<字串,字串>> =的entrySet postData.entrySet();
INT DATALENGTH = entrySet.size();
的NameValuePair [] =對新的NameValuePair [DATALENGTH]
INT I = 0;
對於(進入<String,字串>項:的entrySet)
{
雙[我++] =新的NameValuePair(entry.getKey(),entry.getValue());
}
返回對;
}

/ **
*請求網頁內容資訊
*
* @參數的HttpClient
* @參數reqUrl
*參數標題
* @參數POSTDATA
*參數編碼
* @return
* /
公用靜態字串doRequest(HttpClient的HttpClient的,字串reqUrl,
地圖<字串, String>的頭,地圖<String,字串> POSTDATA,字串編碼)
{
字串htmlContent = NULL;
如果(空== HttpClient的)
{
返回htmlContent;
}

//請求編碼設定
編碼=(空==編碼defaultEncode:編碼);

//頭部請求資訊
列表<標題> =頭getHeaders(頭);

的System.out.println(“[”+ DATE_FORMAT.format(新的Date())+“] - doRequest - ”+ reqUrl);

//交方式
,如果(空= POSTDATA!)
{
的PostMethod的PostMethod =新EncodePostMethod(reqUrl,編碼);
對於(頭tempHeader:頭)
{
postMethod.setRequestHeader(tempHeader);
}

//後參數設定
的NameValuePair [] = PARAMS getPairs(POSTDATA);
如果(空=參數!)
{
postMethod.setRequestBody(PARAMS);
}

//提取網頁內容
htmlContent = executeMethod(HttpClient的,後方法,編碼,getWebSite(reqUrl));
}
其他
{
GetMethod getMethod =新的實現getMethod(reqUrl);
對於(頭tempHeader:頭)
{
getMethod.setRequestHeader(tempHeader);
}

//提取網頁內容
htmlContent = executeMethod(HttpClient的,getMethod,編碼,NULL);
}
返回htmlContent;
}

私人靜態字串getWebSite(字串reqUrl)
{
字串網站= NULL;
如果(空== reqUrl || reqUrl.isEmpty())
{
返回網站;
}

字串首碼=“HTTP://”;
如果(reqUrl.startsWith(首碼))
{
INT指數= reqUrl.substring(prefix.length())的indexOf(“/”)+ prefix.length();
網站= reqUrl.substring(0,索引);
}
返回網站;
}

/ **
*通過列舉HTTPMethod擷取網頁內容
*
* @參數的HttpClient
* @參數requestMethod
*參數編碼
*參數的網站
* @return
* /
私人靜態字串executeMethod(HttpClient的HttpClient的,列舉HTTPMethod requestMethod,編碼字串,字串網站)
{
字串responseContent = NULL;
如果(空== HttpClient的)
{
返回responseContent;
}

//判斷是否請求加密資料
的布爾dataEncrypt = FALSE;
頭acceptEncoding = requestMethod.getRequestHeader(“接受編碼”);
如果(!空= acceptEncoding
。&& acceptEncoding.getValue()包含(“gzip的”))
{
dataEncrypt = TRUE;
}

的InputStream responseStream = NULL;
嘗試
{
INT狀態= httpClient.executeMethod(requestMethod);
如果(HttpStatus.SC_OK ==狀態)
{
responseStream = requestMethod.getResponseBodyAsStream();
responseContent = getContentByStream(dataEncrypt新GZIPInputStream(responseStream):responseStream,編碼);
responseStream.close();
}
//傳回碼為301302303307時,表示頁面己經重新導向,則重新請求位置的URL,這在一些登入授權取餅乾時很重要
否則,如果(HttpStatus.SC_MOVED_PERMANENTLY ==狀態
|| HttpStatus.SC_MOVED_TEMPORARILY ==狀態
|| HttpStatus.SC_SEE_OTHER ==狀態
|| HttpStatus.SC_TEMPORARY_REDIRECT ==狀態)
{
//讀取新的URL地址
頭槌沖頂= requestMethod.getResponseHeader(“位置”);
如果(!頭= NULL)
{
字串的redirectUrl = header.getValue();
如果(零=的redirectUrl!
&&假== redirectUrl.isEmpty())
{
responseContent =無效;
如果(空==的redirectUrl || redirectUrl.isEmpty())
{
的redirectUrl =“/”;
}

如果(假== redirectUrl.startsWith(“HTTP://”)
!&&空=網站)
{
如果(website.startsWith(“/”))
{
的redirectUrl =網站+的redirectUrl;
}
其他
{
的redirectUrl =網站+“/”+的redirectUrl;
}
}

GetMethod重新導向=新的實現getMethod(的redirectUrl);
頭引薦= requestMethod.getRequestHeader(“引薦”);
如果(空=引用者!)
{
redirect.addRequestHeader(引薦);
}
頭的cookie = requestMethod.getRequestHeader(“曲奇”);
如果(空=餅乾!)
{
redirect.addRequestHeader(餅乾);
}
狀態= httpClient.executeMethod(重新導向);
如果(HttpStatus.SC_OK ==狀態)
{
responseStream = redirect.getResponseBodyAsStream();
responseContent = getContentByStream(responseStream,編碼);
responseStream.close();
}
}

} //端頭

} //結束狀態

}趕上(例外五)
{
e.printStackTrace();
}最後
{
如果(requestMethod!= NULL)
{
requestMethod.releaseConnection();
}
}
返回responseContent;
}

/ **
*按照指定編碼從流中讀取資訊
*
* @參數inStream中
*參數編碼
* @返回
*引發IOException
* /
公用靜態字串getContentByStream(的InputStream inStream中,字串編碼)拋出IOException異常
{
如果(空= =插播廣告)
{
返回NULL;
}

StringBuilder的內容=新的StringBuilder();
//採用指定編碼格式讀取流內容
的BufferedReader讀者=新的BufferedReader(新的InputStreamReader(插播廣告,編碼));
字串訊息= NULL;
而(空=(訊息= reader.readLine())!)
{
content.append(訊息);
content.append(“\ r \ n”);
}
//關閉讀取器,釋放資源
reader.close();
返回(content.toString());
}

/ **
*內部類,繼承於的PostMethod,用來指定郵政請求編碼格式
* /
公用靜態類EncodePostMethod擴充的PostMethod
{
私人字串編碼= NULL;

公用EncodePostMethod(URL字串,字串編碼)
{
超(URL);
this.encode =編碼;
}

@覆蓋
公用字串getRequestCharSet()
{
// TODO自動產生方法存根
回報(this.encode);
}

}

/ **
*測試
*
* @參數ARGS
* /
公用靜態無效的主要(字串[] args)
{
//System.setProperty("http.proxyHost“,”165.228.128.10“);
//System.setProperty("http.proxyPort“,”3128“);
//System.setProperty("http.proxySet“,”真“);


字串reqUrl =“ http://news.39.net/jbyw/index.html ”;
reqUrl =“ http://news.39.net/a/2010722/1404231.html ”;
地圖<String,字串>標題=新的HashMap <String,字串>();
headers.put(“接受編碼”,“gzip的,放氣”);

HttpClient的HttpClient的= getHttpClient();
字串htmlContent = doRequest(HttpClient的,reqUrl,頭,空,“GBK”);
的System.out.println(htmlContent);

}
}

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.