1. 程式人生 > >JAVA網路爬蟲(三):HttpClient獲取HTML

JAVA網路爬蟲(三):HttpClient獲取HTML

在本爬蟲專案中採用Httpclient來模擬客戶端瀏覽器,訪問並獲取網頁資源。

HttpClient簡介

Http協議是網際網路中最重要的協議之一。雖然JDK中的java.net包提供了一些http的基本方法,可以通過http協議來訪問網路資源,但是在絕大多數情況下不夠靈活和強大。HttpClient是Apache Jakarta Commom的子專案,致力於填補這個空缺,它提供了有效的,最新的、豐富的包,HttpClient即支援基本的http協議,還支援http-aware客戶端程式,如web瀏覽器,Webservice客戶端,以及利用或擴充套件的http協議的分散式系統。

HttpClient的特性

  • 基於標準、純淨的JAVA語言,實現了Http1.0和1.1,支援Https協議;
  • 在http1.0和http1.1中利用KeepAlive保持持久連線;
  • 實驗性的支援http1.1 response caching;
  • 以可擴充套件的面向物件的結構實現了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE);
  • 通過Http代理建立透明的連線;
  • 利用CONNECT方法通過Http代理建立隧道的Https連線;
  • Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos認證方案及外掛式的自定義認證方案;
  • 便攜可靠的套接字工廠使它更容易的使用第三方解決方案;
  • 連線管理器支援多執行緒應用。支援設定最大連線數,同時支援設定每個主機的最大連線數,發現並關閉過期的連線;
  • 自動處理Set-Cookie中的Cookie及外掛式的自定義Cookie策略;
  • Request的輸出流可以避免流中內容直接緩衝到socket伺服器;
  • Response的輸入流可以有效的從socket伺服器直接讀取相應內容;
  • 直接獲取伺服器傳送的response code和 headers;
  • 設定連線超時的能力;
  • 原始碼基於Apache License 可免費獲取;

HttpClient配置

  • 使用Maven管理專案時,需要在pom中新增依賴如下:
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.4</version>
    </dependency>

HttpClient的使用步驟

使用HttpClient的傳送請求,接收響應很簡單,一般需要如下幾個步驟即可:

  • 建立HttpClient物件;
  • 建立請求方法的例項,並制定請求的URL(用HttpGet來建立GET請求,HttpPost來建立POST請求);
  • 在setParams()方法中新增請求引數,HttpPost物件也可以通過setEntity()方法來設定請求引數;
  • 呼叫HttpClient物件的execute()方法來發送請求,該方法將會返回一個HttpResponse物件;
  • 呼叫HttpResponse物件的getAllHeaders()、getHeaders()等方法可獲取伺服器的響應頭,呼叫getEntity()方法可獲取HttpEntity物件,該物件包裝了伺服器的響應內容;
  • 釋放連結。

使用HttpClient獲取HTML

public String getSource(String url) {
    String html = new String();
    HttpGet httpget = new HttpGet(url);     //建立Http請求例項,URL 如:https://cd.lianjia.com/
    // 模擬瀏覽器,避免被伺服器拒絕,返回返回403 forbidden的錯誤資訊
    httpget.setHeader("User-Agent", 
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36");

    CloseableHttpResponse response = null;
    CloseableHttpClient httpclient = HttpClients.createDefault();   // 使用預設的HttpClient
    try {
        response = httpclient.execute(httpget);
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {     // 返回 200 表示成功
            html = EntityUtils.toString(response.getEntity(), "utf-8");     // 獲取伺服器響應實體的內容
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return html;
}

一般情況下,按照上述步驟,使用如下程式碼便可抓取到鏈家的HTML內容,若要爬需要使用者登入驗證的網站(如最簡單的使用者名稱-密碼認證),則需要使用UsernamePasswordCredentials形成一組安全主體和密碼,該類一般可滿足HTTP標準規範中的認證機制要求。

UsernamePasswordCredentials creds = new UsernamePasswordCredentials("username", "password");
httpclient.getState().setCredentials(AuthScope.ANY, creds); 

HttpClient既支援HTTP標準規範定義的認證模式,又支援一下廣泛使用的非標準認證模式,比如 NTLM 和 SPNEGO。