2015-10-11 45 views
11

我想記錄我的Python腳本下載和上傳的總字節數。Python請求/ urllib - 監控帶寬使用情況

total_downloaded_bytes = 0 
def bandwidth_hook(r, *args, **kwargs): 
    global total_downloaded_bytes 
    total_downloaded_bytes += len(r.content) 
req = requests.session() 
req.hooks = {'response': bandwidth_hook} 

上面的代碼不考慮HTTP壓縮(如果我右)和報頭的尺寸。

有沒有一種方法來統計上傳和下載的總字節數requests.session?如果不是,那麼腳本範圍的計數呢?

回答

4

您可以訪問r.request對象來計算傳出字節,並且您可以通過查看傳入請求的content-length標頭來確定傳入字節(是否壓縮)。這通常足以滿足99%的所有請求。

計算標頭的字節大小很簡單;只是加起來鍵和值lenghts,添加4個字節用於結腸和空白,加2多爲空行:

def header_size(headers): 
    return sum(len(key) + len(value) + 4 for key, value in headers.items()) + 2 

還有初始行;對於請求是{method} {path_url} HTTP/1.1{CRLF},對於響應是HTTP/1.x {status_code} {reason}{CRLF}。這些長度都可以提供給你。然後

總大小爲:

request_line_size = len(r.request.method) + len(r.request.path_url) + 12 
request_size = request_line_size + header_size(r.request.headers) + int(r.request.headers.get('content-length', 0)) 
response_line_size = len(r.response.reason) + 15 
response_size = response_line_size + header_size(r.headers) + int(r.headers.get('content-length', 0)) 
total_size = request_size + response_size 
+0

哇,看起來這樣複雜的東西簡單。感謝你的回答! – Elmo

+1

@Elmo:respone對象是HTTP信息的高級建模,它從來不是一個用來完全重構底層HTTP協議字節的用例。 –

+0

你能不能在更深的地方掛鉤?實際的tcp流或某處? – Elmo