HttpClient(二)HttpClient使用Ip代理與處理鏈接超時

前言java

  其實前面寫的那一點點東西都是輕輕點水,其實HttpClient還有不少強大的功能:數據庫

  (1)實現了全部 HTTP 的方法(GET,POST,PUT,HEAD 等)
  (2)支持自動轉向
  (3)支持 HTTPS 協議
  (4)支持代理 服務器

1、HttpClient使用代理IP

1.一、前言

  在爬取網頁的時候,有的目標站點有反爬蟲機制,對於頻繁訪問站點以及規則性訪問站點的行爲,會採集屏蔽IP措施
  這時候,代理IP就派上用場了。可使用代理IP,屏蔽一個就換一個IP。
  關於代理IP的話 也分幾種 透明代理、匿名代理、混淆代理、高匿代理,通常使用高匿代理。    apache

1.二、幾種代理IP

  1)透明代理(Transparent Proxy)服務器

    REMOTE_ADDR = Proxy IP
    HTTP_VIA = Proxy IP
    HTTP_X_FORWARDED_FOR = Your IP
    透明代理雖然能夠直接「隱藏」你的IP地址,可是仍是能夠從HTTP_X_FORWARDED_FOR來查到你是誰。併發

  2)匿名代理(Anonymous Proxy)dom

    REMOTE_ADDR = proxy IP
    HTTP_VIA = proxy IP
    HTTP_X_FORWARDED_FOR = proxy IP
    匿名代理比透明代理進步了一點:別人只能知道你用了代理,沒法知道你是誰。
    還有一種比純匿名代理更先進一點的:混淆代理maven

  3)混淆代理(Distorting Proxies)測試

    REMOTE_ADDR = Proxy IP
    HTTP_VIA = Proxy IP
    HTTP_X_FORWARDED_FOR = Random IP address
    如上,與匿名代理相同,若是使用了混淆代理,別人仍是能知道你在用代理,可是會獲得一個假的IP地址,假裝的更逼真。ui

  4)高匿代理(Elite proxy或High Anonymity Proxy)url

    REMOTE_ADDR = Proxy IP
    HTTP_VIA = not determined
    HTTP_X_FORWARDED_FOR = not determined
    能夠看出來,高匿代理讓別人根本沒法發現你是在用代理,因此是最好的選擇。
    通常咱們搞爬蟲 用的都是 高匿的代理IP;
    那代理IP 從哪裏搞呢 很簡單 百度一下,你就知道 一大堆代理IP站點。 通常都會給出一些免費的,可是花點錢搞收費接口更加方便。

1.三、實例來使用代理Ip

  使用 RequestConfig.custom().setProxy(proxy).build() 來設置代理IP  

package com.jxlg.study.httpclient;

import com.sun.org.apache.regexp.internal.RE;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
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;

public class UseProxy {
    public static void main(String[] args) throws IOException {
        //建立httpClient實例
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //建立httpGet實例
        HttpGet httpGet = new HttpGet("http://www.tuicool.com");
        //設置代理IP,設置鏈接超時時間 、 設置 請求讀取數據的超時時間 、 設置從connect Manager獲取Connection超時時間、
        HttpHost proxy = new HttpHost("58.60.255.82",8118);
        RequestConfig requestConfig = RequestConfig.custom()
                .setProxy(proxy)
                .setConnectTimeout(10000)
                .setSocketTimeout(10000)
                .setConnectionRequestTimeout(3000)
                .build();
        httpGet.setConfig(requestConfig);
        //設置請求頭消息
        httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36");
        CloseableHttpResponse response = httpClient.execute(httpGet);

        if (response != null){
            HttpEntity entity = response.getEntity();  //獲取返回實體
            if (entity != null){
                System.out.println("網頁內容爲:"+ EntityUtils.toString(entity,"utf-8"));
            }
        }
        if (response != null){
            response.close();
        }
        if (httpClient != null){
            httpClient.close();
        }
    }
}

 

1.四、實際開發中怎麼去獲取代理ip

  咱們可使用HttpClient來 爬取 http://www.xicidaili.com/ 上最新的20條的高匿代理IP,來保存到 鏈表中,當一個IP被屏蔽以後獲取鏈接超時時,

  就接着取出 鏈表中的一個IP,以此類推,能夠判斷當鏈表中的數量小於5的時候,就從新爬取 代理IP 來保存到鏈表中。

1.五、HttpClient鏈接超時及讀取超時

  httpClient在執行具體http請求時候 有一個鏈接的時間和讀取內容的時間

  1)HttpClient鏈接時間

    所謂鏈接的時候 是HttpClient發送請求的地方開始到鏈接上目標url主機地址的時間,理論上是距離越短越快,

    線路越通暢越快,可是因爲路由複雜交錯,每每鏈接上的時間都不固定,運氣很差連不上,HttpClient的默認鏈接時間,據我測試,

    默認是1分鐘,假如超過1分鐘 過一會繼續嘗試鏈接,這樣會有一個問題 假如遇到一個url總是連不上,會影響其餘線程的線程進去,說難聽點,

    就是蹲着茅坑不拉屎。因此咱們有必要進行特殊設置,好比設置10秒鐘 假如10秒鐘沒有鏈接上 咱們就報錯,這樣咱們就能夠進行業務上的處理,

    好比咱們業務上控制 過會再鏈接試試看。而且這個特殊url寫到log4j日誌裏去。方便管理員查看。

  2)HttpClient讀取時間

    所謂讀取的時間 是HttpClient已經鏈接到了目標服務器,而後進行內容數據的獲取,通常狀況 讀取數據都是很快速的,

    可是假如讀取的數據量大,或者是目標服務器自己的問題(好比讀取數據庫速度慢,併發量大等等..)也會影響讀取時間

    同上,咱們仍是須要來特殊設置下,好比設置10秒鐘 假如10秒鐘還沒讀取完,就報錯,同上,咱們能夠業務上處理。     

  好比咱們這裏給個地址 http://central.maven.org/maven2/,這個是國外地址 鏈接時間比較長的,並且讀取的內容多 。很容易出現鏈接超時和讀取超時。  

  咱們如何用代碼實現呢?

  HttpClient給咱們提供了一個RequestConfig類 專門用於配置參數好比鏈接時間,讀取時間以及前面講解的代理IP等。

  例子:

package com.jxlg.study.httpclient;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
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;

public class TimeSetting {
    public static void main(String[] args) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://central.maven.org/maven2/");
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(5000)
                .build();
        httpGet.setConfig(config);
        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36");
        CloseableHttpResponse response = httpClient.execute(httpGet);
        if (response != null){
            HttpEntity entity = response.getEntity();
            System.out.println("網頁內容爲:"+ EntityUtils.toString(entity,"UTF-8"));
        }
        if (response != null){
            response.close();
        }
        if (httpClient != null){
            httpClient.close();
        }
    }
}
相關文章
相關標籤/搜索