天天看點

網站反爬蟲的政策有哪些

網站有許多反爬蟲政策,包括但不限于:1、阻止IP位址:目标網站通過阻止某些IP位址來阻止爬蟲的通路。2、驗證碼:目标網站要求使用者在送出表單時輸入驗證碼,以便爬蟲無法通過表單送出擷取資料。3、User-Agent檢查:目标網站檢查請求的User-Agent資訊,以确定請求是否來自爬蟲。4、Cookie檢查:目标網站通過檢查請求中的Cookie資訊來确定請求是否來自爬蟲。5、反爬蟲機器學習模型:目标網站通過訓練反爬蟲機器模型來識别爬蟲程式的請求。這些政策有一個目的,即防止爬蟲自動從網站抓取資料。

如果你正在編寫爬蟲,你需要考慮這些政策,并采取适當的措施來應對。下面提供兩個demo,分别示範User-Agent随機和IP位址随機。

1、設定User-Agent随機

String[] userAgents = {
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15",
  "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
};

Random rand = new Random();

URL url = new URL("http://www.example.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();

// 設定随機User-Agent
con.setRequestProperty("User-Agent", userAgents[rand.nextInt(userAgents.length)]);

// 發送請求
con.connect();

           

2、使用代理設定随機IP,您可以使用一個存儲多個代理IP和端口的數組,并在每次發送請求時使用數組中的随機值,如下所示:

String[] proxyIps = {
  "192.168.0.1:8080",
  "192.168.0.2:8080",
  "192.168.0.3:8080"
};

Random rand = new Random();

URL url = new URL("http://www.example.com");

// 設定随機代理IP和端口
String[] parts = proxyIps[rand.nextInt(proxyIps.length)].split(":");
String ip = parts[0];
int port = Integer.parseInt(parts[1]);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ip, port));
HttpURLConnection con = (HttpURLConnection) url.openConnection(proxy);

// 發送請求
con.connect();

           

為了提升采集效率,對代理IP還需要進行存活檢查和有效時間判斷。還有一種更簡單的設定随機IP的方法,可以使用爬蟲代理産品,該産品采用隧道IP技術,可以實作自動IP切換,根據HTTP請求情況進行動态IP配置設定,如下所示:

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.util.Random;

class ProxyAuthenticator extends Authenticator {
    private String user, password;

    public ProxyAuthenticator(String user, String password) {
        this.user     = user;
        this.password = password;
    }

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(user, password.toCharArray());
    }
}

/**
 * 注意:下面代碼僅僅實作HTTP請求連結,每一次請求都是無狀态保留的,僅僅是這次請求是更換IP的,如果下次請求的IP位址會改變
 * 如果是多線程通路的話,隻要将下面的代碼嵌入到你自己的業務邏輯裡面,那麼每次都會用新的IP進行通路,如果擔心IP有重複,
 * 自己可以維護IP的使用情況,并做校驗。
 */
public class Demo {
    public static void main(String args[]) throws Exception {
        // Change in Java 8 Update 111 以上版本需要下面代碼
        // System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "false");
        // System.setProperty("jdk.http.auth.proxying.disabledSchemes", "false");

        // 要通路的目标頁面
        String targetUrl = "http://httpbin.org/ip";


        // 代理伺服器(産品官網 www.16yun.cn)
        String proxyServer = "t.16yun.cn";
        int proxyPort      = 31111;

        // 代理驗證資訊
        String proxyUser  = "username";
        String proxyPass  = "password";

        try {
            URL url = new URL(targetUrl);

            Authenticator.setDefault(new ProxyAuthenticator(proxyUser, proxyPass));

            // 建立代理伺服器位址對象
            InetSocketAddress addr = new InetSocketAddress(proxyServer, proxyPort);
            // 建立HTTP類型代理對象
            Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);

            // 設定通過代理通路目标頁面
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);

            // 設定KeepAlive
            // connection.setRequestProperty("Connection", "keep-alive");
            // connection.setRequestProperty("Keep-Alive", "timeout=5, max=100");                

            // 設定Proxy-Tunnel
            // Random random = new Random();
            // int tunnel = random.nextInt(10000);
            // connection.setRequestProperty("Proxy-Tunnel",String.valueOf(tunnel));

            // 解析傳回資料
            byte[] response = readStream(connection.getInputStream());

            System.out.println(new String(response));
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

    /**
     * 将輸入流轉換成字元串
     *
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;

        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();

        return outSteam.toByteArray();
    }
}

           

上面的代碼使用了Java的HttpURLConnection類實作了通過代理IP發送HTTP請求。具體來說,它建立了一個代理伺服器位址對象并将其設定為HTTP類型的代理對象,然後通過調用openConnection()方法傳遞這個代理對象來打開一個到目标頁面的連接配接。随後,它設定了代理驗證資訊并發送請求。

此外,上面的代碼還實作了随機IP請求。具體來說,它定義了一個存儲多個代理IP和端口的數組,并使用Java的Random類在每次發送請求時随機選擇一個值作為代理IP和端口。