1. 程式人生 > >自己搭建億級爬蟲IP代理池

自己搭建億級爬蟲IP代理池

做爬蟲抓取時,我們經常會碰到網站針對IP地址封鎖的反爬蟲策略。但只要有大量可用的IP資源,問題自然迎刃而解。

以前嘗試過自己抓取網路上免費代理IP來搭建代理池,可免費IP質量參差不齊,不僅資源少、速度慢,而且失效快,滿足不了快速密集抓取的需求。

收費代理提供的代理資源質量明顯提升,經過多家測試,最終選定使用站大爺作為代理提供平臺。

站大爺代理IP平臺每天能提供大概24萬個不重複的短效高匿代理,每個代理存活期為3分鐘,總IP數有20億,IP數量足夠使用。價格為包天17元,包月475元,還有半年及一年的套餐可供選擇。只要能滿足專案要求,提供優質穩定的服務,這些成本值得付出。

高匿代理才可以真正用來防止爬蟲被封鎖,如果使用普通代理,爬蟲的真實

IP還是會暴露。

搭建思路

站大爺提供了大量的代理伺服器資源,主要考慮如何將這些伺服器分配給爬蟲伺服器使用。最初的想法是使用Redis作為代理伺服器資源佇列,一個程式自動獲取站大爺API提供的代理,驗證可用後pushRedis裡,每個程式再從Redispop一個代理進行抓取,但這樣的缺點是不太好控制每臺爬蟲伺服器的代理質量,有的代理速度快,有的速度比較慢,影響抓取效率,其次就是需要自行維護一套代理驗證、分配的程式,增加了程式碼量,不便後期維護。

為了解決這些問題,我想到可以使用Squid提供的父代理功能,自動將爬蟲伺服器的請求轉發給代理伺服器。Squid提供了自動輪詢功能,自動驗證並剔除不可用的代理。減少了我們多餘的驗證步驟。

爬蟲軟體只需將代理設定為Squid伺服器即可,不需要每次重新設定為其他的代理伺服器。

這套方案明顯減少了工作量,提高了易用性和可維護性。

實現過程

1.      首先獲取代理平臺提供的代理伺服器資源

o  建議購買短效代理,購買後在後臺獲取API地址並設定IP白名單等引數

2.      將獲取到的代理伺服器寫入squid配置檔案

o  解析網站提供的代理伺服器,按照一定規則寫入/etc/squid/squid.conf

3.      

重新配置squid

o  寫入配置檔案之後重新載入最新的檔案,不會造成中斷

4.      自動更新,重複1-3

o  由於網站提供的代理存活時間只有2分鐘,所以需要每隔一段時間重新獲取一批新IP

實現上述要求的程式碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

#!/usr/bin/env python

# coding: utf-8

# zdy.py

'''

Squid+站大爺搭建代理IP池

Author: Nathan

Blog: www.xnathan.com

Github: github.com/xNathan

'''

import os

import time

import requests

# Squid的配置檔案語法

# 將請求轉發到父代理

PEER_CONF = "cache_peer %s parent %s 0 no-query weighted-round-robin weight=1 connect-fail-limit=2 allow-miss max-conn=5\n"

def update_conf(proxies):

    with open('/etc/squid/squid.conf.original', 'r') as F:

        squid_conf = F.readlines()

    squid_conf.append('\n# Cache peer config\n')

    for proxy in proxies:

        squid_conf.append(PEER_CONF % (proxy[0], proxy[1]))

    with open('/etc/squid/squid.conf', 'w') as F:

        F.writelines(squid_conf)

def get_proxy():

    # 1. 獲取代理IP資源

    api_url = 'http://s.zdaye.com/?api=YOUR_API&count=100&fitter=1&px=2'

    res = requests.get(api_url).content

    if len(res) == 0:

        print 'no data'

    elif 'bad' in res:

        print 'bad request'

    else:

        print 'get all proxies'

        proxies = []

        for line in res.split():

            proxies.append(line.strip().split(':'))

        # 2. 寫入Squid配置檔案

        update_conf(proxies)

        # 3. 重新載入配置檔案

        os.system('squid -k reconfigure')

        print 'done'

def main():

    start = time.time()

    while True:

        # 60秒獲取一批新IP

        if time.time() - start >= 60:

            get_proxy()

        time.sleep(5)

        start = time.time()

if __name__ == '__main__':

    main()

使用方法

1.      Squid 搭建正向代理伺服器Squid 配置高匿代理介紹的方法搭建執行Squid高匿伺服器

2.      備份原始配置檔案cp/etc/squid/squid.conf /etc/squid/squid.conf.original,以供軟體使用

3.      squid伺服器上執行python zdy.py

例項

如果按照上述方法搭建好代理IP池,只需要在爬蟲程式碼中設定設定squid代理伺服器地址和埠(比如139.xxx.xxx.66:3188)

1

2

3

4

5

6

7

8

9

10

11

12

#!/usr/bin/env python

# coding: utf-8

'''

代理IP池例項演示

'''

import requests

s = requests.Session()

s.proxies.update(

    {'http': '139.xxx.xxx.66:3188'}

)

print s.get('http://httpbin.org/ip')

每次執行這個程式時,返回的IP都不一樣,而且僅有一個,說明IP代理池已經搭建成功,可以應用在網路爬蟲專案中。

總結

這套解決方案結合了網路上的大量優質代理資源以及Squid伺服器提供的特性,基本解決了網站對於爬蟲IP的封鎖。

成本比較低,而且有比較高的易用性,很方便地能結合到各種爬蟲應用中,只需要增加一個代理地址即可,而由Squid統一管理父代理,不需要在爬蟲程式中進行代理的獲取驗證等等操作,便於維護。

實際使用中還沒有發現什麼特別重大的問題,更多擴充套件性還有待後續繼續研究。

專案地址: https://github.com/xNathan/squid_proxy_pool