HttpClient使用Ip代理訪問目標IP

一、HttpClient使用代理IP

1.1、前言

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

1.2、幾種代理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)

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

  3)混淆代理(Distorting Proxies)

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

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

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

1.3、來使用代理Ip

 這裏是一個demo   

package com.ifunpay.portal.service.payment;


import com.icbc.api.internal.apache.http.HttpEntity;
import com.icbc.api.internal.apache.http.HttpHost;
import com.icbc.api.internal.apache.http.HttpStatus;
import com.icbc.api.internal.apache.http.client.config.RequestConfig;
import com.icbc.api.internal.apache.http.client.methods.CloseableHttpResponse;
import com.icbc.api.internal.apache.http.client.methods.HttpGet;
import com.icbc.api.internal.apache.http.client.methods.HttpPost;
import com.icbc.api.internal.apache.http.impl.client.CloseableHttpClient;
import com.icbc.api.internal.apache.http.impl.client.HttpClients;
import com.icbc.api.internal.apache.http.util.EntityUtils;
import com.ifunpay.portal.util.HttpsClient;
import com.ifunpay.portal.util.Md5Encrypt;
import com.ifunpay.util.payment.ShortPaymentRemark;
import lombok.extern.log4j.Log4j2;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @Author: lilong
 * @Data: Created on 2019/11/7
 * @Desc:
 */
@Component
@DependsOn("applicationConfig")
@Log4j2
public class CcbPandaPaymentManager {
    public  String requestQrCode(String orderId,Long totalAmount,Long commerceId) throws IOException {
        String PUB = "30819d300d06092a864886f70d010101050003818b0030818702818100a58c0acb85c38d944e32e41c632adb05de9ae711e155392c75877ea628d259006cdf782a3cf9b6417b625b3fe70da552cefdc0425225232bdbe7544cef0d190144dac368b910030a9d06e366ace810de8a4f250c0b6ecd9bb0d3d33d6495a4305c35aab2f2af26c398b8b0a7c2da93133b8bfa298c94f2382721063a8558b10f020111";

        String ORDERID=orderId;
        double amount = totalAmount;
        String PAYMENT=(amount/100)+"";
        String CURCODE="01";
        String REMARK1= "test";
        ShortPaymentRemark remark = new ShortPaymentRemark();
        //remark.setPaymentAccount(bankPayInfo.getId());
        remark.setPaymentAccount("ccbPanda");
        String remarkFront = remark.genRemark();
        String REMARK2=remarkFront+"@"+commerceId;

        String RETURNTYPE="1";
        String TIMEOUT="";
        String PUB32TR2=PUB.substring(PUB.length()-30);

        String bankURL= "http://localhost:33811/test/IBSVersion=V6";
        StringBuffer tmp = new StringBuffer();
        tmp.append("MERCHANTID=");
        tmp.append("123123123");
        tmp.append("&POSID=");
        tmp.append("369369369");
        tmp.append("&BRANCHID=");
        tmp.append("00000000");
        tmp.append("&SUB_MERCHANTID=");
        tmp.append("");
        tmp.append("&ORDERID=");
        tmp.append(ORDERID);
        tmp.append("&PAYMENT=");
        tmp.append(PAYMENT);
        tmp.append("&CdtrWltId=");
        tmp.append("");
        tmp.append("&CURCODE=");
        tmp.append(CURCODE);
        tmp.append("&TXCODE=");
        tmp.append("PDP000");
        tmp.append("&REMARK1=");
        tmp.append(REMARK1);
        tmp.append("&REMARK2=");
        tmp.append(REMARK2);
        tmp.append("&RETURNTYPE=");
        tmp.append(RETURNTYPE);
        tmp.append("&TIMEOUT=");
        tmp.append(TIMEOUT);
        String tmp0 = tmp.toString();
        tmp.append("&PUB=");
        tmp.append(PUB32TR2);
        log.info("signParams:"+tmp);
        String URL = bankURL+"&"+tmp0+"&MAC=" + Md5Encrypt.md5(tmp.toString());
        URL +="&QRCODE=1&CHANNEL=1";
        log.debug("CcbPandaPayUrl:"+URL);
        HttpHost proxy = new HttpHost("120.24.62.4",18888);
        RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
        //實例化CloseableHttpClient對象
        CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(config).build();
        //HttpGet httpGet = new HttpGet(URL.replaceAll("&", "%26").replaceAll("=","%3D"));
        HttpPost httpPost = new HttpPost(URL);
        //請求返回
        CloseableHttpResponse httpResp = httpclient.execute(httpPost);
        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                System.out.println("成功");
            }
            if (httpResp != null){
                HttpEntity entity = httpResp.getEntity();  //獲取返回實體
                if (entity != null){
                    System.err.println("返回內容爲:"+ EntityUtils.toString(entity,"utf-8"));
                }
            }
        } catch (Exception e) {

        } finally {
            httpResp.close();
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
        CcbPandaPaymentManager ccbPandaPaymentManager = new CcbPandaPaymentManager();
        String result = ccbPandaPaymentManager.requestQrCode(System.currentTimeMillis()+"",100l,11111l);
        System.err.println(result);
    }
}

1.4、實際開發中怎麼去獲取代理ip

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

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

1.5、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等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章