根據請求的url、請求方法、請求參數、請求體進行唯一標識,進行比對,由於這四個數據加到一起,內容較長,因此使用求指紋的方式來進行去重判斷。
指紋計算方法,最常用的就是md5、sha1等hash加密算法,來求指紋,找個地方保存指紋即可
def _to_bytes(string):
"""爲了兼容py2和py3,利用_to_bytes方法,把所有的字符串轉化爲字節類型"""
if six.PY2:
if isinstance(string, str):
return string
else: # 如果是python2的unicode類型,轉化爲字節類型
return string.encode('utf-8')
elif six.PY3:
if isinstance(string, str): # 如果是python3的str類型,轉化爲字節類型
return string.encode("utf-8")
else:
return string
def gen_fp(url, method, data={}):
# 1. url排序:藉助w3lib.url模塊中的canonicalize_url方法
url = w3lib.url.canonicalize_url(url)
# 2. method不需要排序,只要保持大小寫一致就可以 upper()方法全部轉換爲大寫
method = method.upper()
# 3. data排序:如果有提供則是一個字典,如果沒有則是空字典
data = data if data is not None else {}
data = sorted(data.items(), key=lambda x: x[0]) # 用sorted()方法 按data字典的key進行排序
# items()返回元祖 key參數表示按什麼進行排序 x表示data.items() x[0]表示元祖第一個值,也就是data的鍵
# 4. 利用sha1計算獲取指紋
s1 = sha1()
s1.update(_to_bytes(url)) # sha1計算的對象必須是字節類型
s1.update(_to_bytes(method))
s1.update(_to_bytes(str(data)))
fp = s1.hexdigest()
return fp
調用gen_fp(),傳入相應的參數,返回的是加密過後的指紋,直接用來存儲,建議使用redis 速度比較快,要做好持久化
簡單的redis實現的代碼,僅供參考
import redis
def add_hash_value(r, value):
# 如果不存在,把這個值給存進去
r.sadd("myset", value)
def existence(r, value):
# 校驗是否存在這個值
result = r.sismember("myset", value)
if not result:
# 不存在調用這個函數
add_hash_value(r, value)
# 返回查詢結果,供查詢者使用
return result
if __name__ == '__main__':
r = redis.Redis(host='127.0.0.1', port=6379)
value = "b"
print(existence(r, value))