2015-10-11 30 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