Django使用中介軟體進行流量統計
為了統計網站訪問流量,計劃做一個訪問資訊統計,
配置:Ubuntu18.4,阿里雲伺服器,已經執行的Django專案(可以現在本地測試),為了便於檢視,本地最好安裝redis desk manager客戶端,客戶端連線雲伺服器流程,可以看另一篇文章:
redis desk manager 遠端連線阿里雲伺服器Redis服務(Ubuntu18.4)
思路:利用Django所有請求都要經過中介軟體的特點,在中介軟體中獲取request.META中的訪問資訊,存入資料庫,考慮到效率,這裡使用了redis資料庫。所以,電腦上需要安裝redis,sudo apt-get install redis-server
流程如下:
1,新建中介軟體檔案
在Django專案目錄下,新建VisitCountMiddleware.py檔案,
定義中介軟體類,
內容如下:
import time import redis # 注意類名必須是以Middleware結尾。 class VisitCountMiddleware(object): """ 訪問統計 """ def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 獲取request屬性, request_meta = request.META response = self.get_response(request) # 對要獲取的引數進行判斷,防止因沒有引數而丟擲異常 # ip地址 if request_meta.get("HTTP_X_FORWARDED_FOR"): ip = request_meta["HTTP_X_FORWARDED_FOR"] else: ip = request_meta["REMOTE_ADDR"] # 起始路徑,可以統計在網站內部的訪問記錄,如:從A到B,起始路徑就是A if request_meta.get('HTTP_REFERER'): HTTP_REFERER = request_meta['HTTP_REFERER'] else: HTTP_REFERER = False # 目標路徑,就是上面說到的B if request_meta.get('PATH_INFO'): PATH_INFO = request_meta['PATH_INFO'] else: PATH_INFO = False # User-agent,這一項也可以用來過濾請求 if request_meta.get('HTTP_USER_AGENT'): HTTP_USER_AGENT = request_meta['HTTP_USER_AGENT'] else: HTTP_USER_AGENT = False # 請求方式 if request_meta.get('REQUEST_METHOD'): REQUEST_METHOD = request_meta['REQUEST_METHOD'] else: REQUEST_METHOD = False # 連線方式, if request_meta.get('HTTP_CONNECTION'): HTTP_CONNECTION = request_meta['HTTP_CONNECTION'] else: HTTP_CONNECTION = False # 響應碼 response_code = response.status_code visit_time = time.strftime("%Y-%m-%d %H:%M:%S") # 組裝資料,新增訪問時間visit_time info_list = { 'IP': ip, 'Begin_path': HTTP_REFERER, 'End_path': PATH_INFO, 'User_agent': HTTP_USER_AGENT, 'Request_method': REQUEST_METHOD, 'Connection': HTTP_CONNECTION, 'Response_code': response_code, 'Visit_time': visit_time } # 呼叫儲存資料庫函式,存入資料庫 self.save_to_redis(info_list) return response
2,定義資料庫函式
由於redis是NoSQL,是以鍵值對方式儲存資訊的,所以,每一條訪問記錄,都要給它一個鍵,我這裡使用關鍵字+數字做為鍵名,為了避免頻繁的想資料庫發起連線請求,這裡使用連線池,
# 連線池放到VisitCountMiddleware類外面, pool = redis.ConnectionPool(host='127.0.0.1', password='密碼', port=6379, db=0) # 函式放到VisitCountMiddleware內部, def save_to_redis(self, result): """ 儲存至Redis資料庫 :param result: type: dict :return: """ # 資料庫鍵名編號num,也是訪問次數,從1開始 num = 0 # 連線資料庫,try一下,捕獲異常 try: conn = redis.Redis(connection_pool=pool) # 在資料庫中有訪問次數,就是用資料庫中的,如果沒有(第一次),就使用上面的num=0, if conn.get('number'): # 因為redis資料庫中鍵值對的值是以str型別儲存的,下面需要進行加操作,因此需要轉換成int num = int(conn.get('number')), except ConnectionError as e: print(e, '連線redis資料庫失敗') # 儲存資料 try: num += 1 # 這裡使用format動態建立鍵名,因為result是字典,所有,儲存資料庫時使用Hash資料型別, conn.hmset('visit_info{}'.format(num), result) # 如果資料儲存如資料庫,再把num存入資料庫,鍵名為‘number’ conn.set('number', num) print('成功存入redis資料庫') except Exception as e: print(e, '儲存redis資料庫失敗')
這裡還可以統計固定時間內,同一IP的訪問次數,比如1分鐘內同一ip的訪問量,可以用來過濾爬蟲等非正常訪問。不過這不是本次的目的,下次再說。
3,配置生效
把中介軟體新增到Django專案setting內MIDDLEWARE列表內,這裡要注意路徑,比如我們的中介軟體檔案是放在專案根目錄下,檔名 VisitCountMiddleware.py,類名VisitCountMiddleware,就新增 "VisitCountMiddleware.VisitCountMiddleware",
如果在別的資料夾,就要把路徑加上。
4,效果圖:
如果沒有安裝redis desk manager,就在雲伺服器檢視,遠端登入雲伺服器,redis-cli啟動redis,(如有密碼,需要輸入密碼驗證:auth 密碼
),我們儲存在0號庫,啟動redis後,預設進入0庫,不需要另行選擇,如果存在別的庫(連線池中的db選項),使用select 庫名
,切換庫,keys *
檢視庫中的所有鍵名,查詢一個鍵名內的所有資訊,用hgetall 鍵名
。檢視單個鍵的一個屬性用hget 鍵名 加資料字典的鍵名
,如我們檢視第38條訪問的ip資訊,命令就是 hget visit_info38 IP
如圖