1. 程式人生 > >Java 爬蟲實戰案例三之 HttpClient 詳解

Java 爬蟲實戰案例三之 HttpClient 詳解

Java 爬蟲實戰案例三之 HttpClient 詳解

1. 程式碼

package httpClient;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.
HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; /** * 1.this class is used to get a html by HttpClient */ public class HelloHttp { public static void main(String[] args) throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault();
//建立httpClient例項 HttpGet httpGet = new HttpGet("http://www.csdn.net"); //建立httpGet例項 CloseableHttpResponse response = httpClient.execute(httpGet);//指向http get請求 HttpEntity entity = response.getEntity();//獲取返回實體 System.out.println("網頁內容:"+ EntityUtils.toString(entity,"utf-8"));//獲取網頁內容
response.close(); httpClient.close(); } }

2. 執行結果

網頁內容:<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="referrer"content="always">
····
})
</script>
<script src='//csdnimg.cn/pubfooter/js/publib_footer-1.0.3.js?v201807020000' data-isfootertrack="false"></script>
 window.csdn.indexSuperise({
      smallMoveImg: '//ubmcmm.baidustatic.com/media/v1/0f0002xZEmQ-Pg-yUBISo0.png',
      bigMoveImg: '//ubmcmm.baidustatic.com/media/v1/0f0002xZEmU-Pg-yUBISC0.png',
     link:'//edu.csdn.net/topic/python115?utm_source=rightpopup',
trackSuperId: 647
    });
</script></div></html>

3. 問題

3.1 遮蔽請求

但是問題會隨著請求網址的變化而變化。如果將上述的網址由www.csdb.net變換成www.tuicool.com時,就會發現出現如下的執行結果:

網頁內容:<!DOCTYPE html>
<html>
    <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>
        <p>系統檢測親不是真人行為,因系統資源限制,我們只能拒絕你的請求。如果你有疑問,可以通過微博 http://weibo.com/tuicool2012/ 聯絡我們。</p>
    </body>
</html>

這是因為我們單純使用程式是無法獲取被限制的資源的,那麼該如何解決呢?
解決辦法很簡單,我們只需要在請求httpGet中新增一個請求頭即可,如下:
httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0");
有人會問,這個 User-Agent是什麼?這個代表的意思就是:使用的代理使用者,這裡新增上述語句的原因在於,模擬瀏覽器傳送一個請求。這個User-Agent的值可以在瀏覽器中檢視得到。
在這裡插入圖片描述

接著執行程式得到的結果如下:

網頁內容:<!DOCTYPE HTML>

<!--
 ______________ 
< TUICOOL.COM >
 -------------- 
        \   ^__^
         \  (**)\__$__$__
            (__)\       )\/\
             U  ||------|
                ||     ||
-->
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="J+HCJtgjgLVvVpjfK4imYYZ1TAQYONE+cMG8aXDYlpEfn6mc0xx2Q/b3/wwm3FPmXFw0sdj4dCerVtH9ZvNYdA==" />
    <title>
            推酷 - IT人專屬的個性聚合閱讀社群 - 推酷
···                     
    <div style="display:none;">
      <script src="https://s22.cnzz.com/stat.php?id=5541078&web_id=5541078" language="JavaScript"></script>
    </div>

    <script type="text/javascript" src="https://static2.tuicool.com/assets/tip.js?t=3" async></script>
</body>
</html>

如果再更改程式如下:

 public static void main(String[] args) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();//建立httpClient例項
        HttpGet httpGet = new HttpGet("http://www.tuicool.com"); //建立httpGet例項
        httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0");
        CloseableHttpResponse response = httpClient.execute(httpGet);//指向http get請求
        HttpEntity entity = response.getEntity();//獲取返回實體    
        System.out.println("Content-Type :"+entity.getContentType());//獲取內容型別
        System.out.println("Status : "+response.getStatusLine());//判斷響應狀態

        response.close();
        httpClient.close();
    }

執行結果如下:
在這裡插入圖片描述

其中 Content-Type 表示的是獲取到的實體內容屬於什麼型別;Status表示的是這個請求的響應狀態是什麼。如果此時將請求地址寫為:http://www.tuicool.com/dsfsd,再次測試結果如下:
在這裡插入圖片描述
因為這個地址是明顯不存在的,所以請求的 Status 變為了404,但是因為仍然有請求的內容,所以Content-Type仍然是 text/html

3.2 遮蔽IP

因為部分原因,可能會導致發出請求的主機ip被伺服器的反爬蟲程式監控到,這樣就會導致反爬蟲程式將ip拉入黑名單,如果我們開發的程式再以此ip發出請求時,就會拒絕請求。那麼這個問題該怎麼解決呢?
解決方法很簡單,主要是通過使用代理ip的方式,能夠解決上述問題的方法就是使用“高匿代理”,這是一種代理ip,我們使用此代理ip,就可以實現安全的訪問目標主機了。但是這個“高匿代理”的ip怎麼獲取呢?很簡單,baidu一下即可。如下所示:
在這裡插入圖片描述
從中隨機選擇一個,再修改一下我們的程式碼,如下所示:

    public static void main() throws IOException{
        CloseableHttpClient httpClient = HttpClients.createDefault();//建立httpClient例項
        HttpGet httpGet = new HttpGet("http://www.tuicool.com/"); //建立httpGet例項

        HttpHost proxy = new HttpHost("114.235.22.147", 9000);
        RequestConfig config = RequestConfig
                .custom()
                .setProxy(proxy)
                .setConnectTimeout(10000)//連線超時
                .setSocketTimeout(10000)//讀取超時
                .build();
        httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0");

        CloseableHttpResponse response = httpClient.execute(httpGet);//指向http get請求

        HttpEntity entity = response.getEntity();//獲取返回實體

        //System.out.println("網頁內容:"+ EntityUtils.toString(entity,"utf-8"));//獲取網頁內容
        System.out.println("Content-Type :"+entity.getContentType());//獲取內容型別
        System.out.println("Status : "+response.getStatusLine());//判斷響應狀態

        response.close();
        httpClient.close();
    }

執行結果如下:
在這裡插入圖片描述