目前有不少網站提供免費代理,並且種類齊全,好比各個地區、各個匿名級別的都有,不過質量實在不敢恭維,畢竟都是免費公開的,可能一個代理無數我的在用也說不定。因此咱們須要作的是大量抓取這些免費代理,而後篩選出其中可用的代理存儲起來供咱們使用,不可用的進行剔除。git
維護一個代理池第一步就是要找到提供免費代理的站點,例如PROXY360,網頁內容以下:github
能夠看到網頁裏提供了一些免費代理列表,包括服務器地址、端口、代理種類、地區、更新時間等等信息。redis
當前咱們須要的就是代理服務器和端口信息,將其爬取下來便可。數據庫
那麼爬取下代理以後怎樣保存呢?服務器
首先咱們須要確保的目標是能夠邊取邊存,另外還須要定時檢查隊列中不可用的代理將其剔除,因此須要易於存取。app
另外怎樣區分哪些是最新的可用的,哪些是舊的,若是用修改時間來標註是能夠的,不過更簡單的方法就是維護一個隊列,只從一端存入,例如右端,這樣就能確保最新的代理在隊列右端,而在左端則是存入時間較長的代理,若是要取一個可用代理,從隊列右端取一個就行了。網站
那麼對於隊列的左端,不能讓它一直老化下去,還須要作的操做就是定時從隊列左端取出代理,而後進行檢測,若是可用,從新將其加入右端。url
經過以上操做,就保證了代理一直是最新可用的。spa
因此目前來看,既能高效處理,又能夠作到隊列動態維護,合適的方法就是利用Redis數據庫的隊列。代理
能夠定義一個類來維護一個Redis隊列,好比get方法是批量從左端取出代理,put方法是從右端放入可用代理,pop方法是從右端取出最新可用代理。
import redis from proxypool.error import PoolEmptyError from proxypool.setting import HOST, PORT class RedisClient(object): def __init__(self, host=HOST, port=PORT): self._db = redis.Redis(host, port) def get(self, count=1): proxies = self._db.lrange("proxies", 0, count - 1) self._db.ltrim("proxies", count, -1) return proxies def put(self, proxy): self._db.rpush("proxies", proxy) def pop(self): try: return self._db.rpop("proxies").decode('utf-8') except: raise PoolEmptyError
那麼如何來檢測代理是否可用?可使用這個代理來請求某個站點,好比百度,若是得到正常的返回結果,那證實代理可用,不然代理不可用。
conn = RedisClient() proxies = {'http': proxy} r = requests.get('https://www.baidu.com', proxies=proxies) if r.status_code == 200: conn.put(proxy)
例如在這裏proxy就是要檢測的代理,使用requests庫設置好這個代理,而後請求百度,正常請求,那就能夠將這個代理存入Redis。
如今咱們維護了一個代理池,那麼這個代理池須要是能夠公用的。
好比如今有多個爬蟲項目都須要用到代理,而代理池的維護做爲另外的一個項目,他們之間若是要創建鏈接,最恰當的方式就是接口。
因此能夠利用Web服務器來實現一個接口,其餘的項目經過請求這個接口獲得內容獲取到一個可用代理,這樣保證了代理池的通用性。
因此要實現這個還須要一個Web服務器,例如Flask,Tornado等等。
例如使用Flask,定義一個路由,而後調用的RedisClient的pop方法,返回結果便可。
@app.route('/') def get_proxy(): conn = RedisClient() return conn.pop()
這樣一來,整個程序運行起來後,請求網頁就能夠看到一個可用代理了。
使用代理時只須要請求這個站點,就能夠拿到可以使用的代理了。
def get_proxy(): r = requests.get('http://127.0.0.1:5000') return r.text def crawl(url, proxy): proxies = {'http': get_proxy()} r = requests.get(url, proxies=proxies) # do something
能夠定義一個簡單的方法,返回網頁內容即代理,而後在爬取方法裏設置代理使用便可。
https://github.com/Germey/ProxyPool
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處