1. 程式人生 > >搭建一個自己的百萬級爬蟲代理ip池.

搭建一個自己的百萬級爬蟲代理ip池.

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

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

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

飛蟻代理代理IP平臺每天能提供大概200萬個不重複的短效高匿代理,每個代理存活期為1-30分鐘,總IP數有200多萬,IP數量足夠使用。價套餐靈活,按照ip數量與時長計費,可以按照日結,周結與月結,還有半年及一年的套餐可供選擇。只要能滿足專案要求,提供優質穩定的服務,這些成本值得付出。

高匿代理ip才可以真正用來防止爬蟲被封鎖,如果使用普通代理,爬蟲的真實IP還是會暴露。

搭建思路

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

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

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

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

實現過程

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

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

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

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

3.重新配置squid

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

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

o由於網站提供的代理存活時間只有1-30分鐘(由套餐決定),所以需要每隔一段時間重新獲取一批新IP

#!/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 ”

def update_conf(proxies):

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

squid_conf = F.readlines()

squid_conf.append(‘ # Cache peer config ‘)

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資源

http://proxy.360pdown.com:88/open?user_name=lt_test_1&timestamp=15889653664&md5=00112233445566778899AABBCCDDEEFF&pattern=json&number=2&province=510000&city=510100

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)。

#!/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統一管理父代理,不需要在爬蟲程式中進行代理的獲取驗證等等操作,便於維護。

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