Flask+Redis維護代理池

聲明:此篇文章主要是觀看靜覓教學視頻後作的筆記,原教程地址https://cuiqingcai.com/python

  普通代理git

    由於以前都是學習測試,不須要對網站頻繁的搜索爬取,因此代理使用彷佛關係不大,不過爲了防止IP被封,也是一個很重要的知識點。以前使用代理也都是查找一些代理網站,手動將IP設置添加到proxies參數中,比較麻煩,並且代理IP也有可能出現沒法正常訪問的狀況github

import requests

proxies = {
  "http": "http://127.0.0.1:9743",
  "https": "https://127.0.0.1:9743",
}
response = requests.get("https://www.taobao.com", proxies=proxies)

維護代理池web

1.爲何要用代理池許多網站有專門的反爬蟲措施,可能遇到封IP等問題  
    ①互聯網上公開了大量免費代理,利用好資源
    ②經過定時的檢測維護一樣能夠獲得多個可用代理redis

2.代理池的要求
    ①多站抓取,異步檢測
    ②定時篩選,持續更新
    ③提供接口,易於提取數據庫

3.代理池的架構
   proxy_pool.jpeg服務器

4.代理池的獲取途徑   
    如今,新增一個解決思路,那就是經過Flask+Redis維護代理池。免費代理的質量可能不是太好,可能一個代理無數我的在用也說不定,主要實現就是從免費代理網站大量抓取這些免費代理,而後篩選出其中可用的代理存儲起來供咱們使用,不可用的進行剔除,以西刺免費代理IP爲例    proxy_list.png       架構

    能夠看到網頁裏提供了一些免費代理列表,包括服務器地址、端口、代理種類、地區、更新時間等等信息。當前咱們須要的就是代理服務器和端口信息,將其爬取下來便可app

5.維護代理
    代理被爬取下來以後,就要解決代理的保存問題。首先咱們須要確保的目標是能夠邊取邊存,另外還須要定時檢查隊列中不可用的代理將其剔除,因此須要易於存取。
    另外怎樣區分哪些是最新的可用的,哪些是舊的,若是用修改時間來標註是能夠的,不過更簡單的方法就是維護一個隊列,只從一端存入,例如右端,這樣就能確保最新的代理在隊列右端,而在左端則是存入時間較長的代理,若是要取一個可用代理,從隊列右端取一個就行了。那麼對於隊列的左端,不能讓它一直老化下去,還須要作的操做就是定時從隊列左端取出代理,而後進行檢測,若是可用,從新將其加入右端
    經過以上操做,就保證了代理一直是最新可用的。因此目前來看,既能高效處理,又能夠作到隊列動態維護,合適的方法就是利用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

6.檢測代理
    可使用這個代理來請求某個站點,好比百度,若是得到正常的返回結果,那證實代理可用,不然代理不可用

import requests

conn = RedisClient()
proxies = {'http': proxy}
r = requests.get('https://www.baidu.com', proxies=proxies)
if r.status_code == 200:
    conn.put(proxy)

7.獲取可用代理
    經過redis-desktop能夠看到一個proxies的鍵,其內容就是一些可用的IP代理,也就是所維護的代理池

   2018-08-07 10-25-49屏幕截圖.png

    維護了一個代理池,那麼這個代理池須要是能夠公用的。好比如今有多個爬蟲項目都須要用到代理,而代理池的維護做爲另外的一個項目,他們之間若是要創建鏈接,最恰當的方式就是接口。因此能夠利用Web服務器來實現一個接口,其餘的項目經過請求這個接口獲得內容獲取到一個可用代理,這樣保證了代理池的通用性。因此要實現這個還須要一個Web服務器,例如Flask,Tornado等等。例如使用Flask,定義一個路由,而後調用RedisClient的pop方法,返回結果便可

@app.route('/')
def get_proxy():
    conn = RedisClient()
    return conn.pop()

    這樣一來,整個程序運行起來後,請求網頁就能夠看到一個可用代理了

8.使用代理
    使用代理時只須要請求這個站點,就能夠拿到可以使用的代理了。

web_ip.jpg

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

    能夠定義一個簡單的方法,返回網頁內容即代理,而後在爬取方法裏設置代理使用便可

10.代理池功能測試
    在瞭解了前面內容以後,現學現用,立刻用代理池測試訪問了個人站點

11.代理池完整源碼
    我是從崔家華老師的github上下載下來的,源碼可參考:https://github.com/Germey/ProxyPool  

    下載後發現源碼不能正常安裝,發現是在setup.py文件中有個參數配置錯誤

# 將
packages=[
        'proxy-pool'
    ],
# 改成
packages=[
        'proxypool'
    ],

    修改後的項目地址:https://github.com/XiaoFei-97/ProxyPool

原文出處:https://www.jzfblog.com/detail/68,文章的更新編輯以此連接爲準。歡迎關注源站文章!

相關文章
相關標籤/搜索