搭建一個自己的百萬級爬蟲代理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資源
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統一管理父代理,不需要在爬蟲程式中進行代理的獲取驗證等等操作,便於維護。
實際使用中還沒有發現什麼特別重大的問題,更多擴充套件性還有待後續繼續研究