Python Requests/urllib - 监控带宽使用情况

Elm*_*lmo 12 python bandwidth python-requests

我想记录我的Python脚本下载和上传的总字节数.

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}
Run Code Online (Sandbox Code Playgroud)

上面的代码没有考虑HTTP压缩(如果我是对的)和标头的大小.

有没有办法从requests.session计算上传和下载的总字节数?如果没有,那么脚本范围的计数呢?

Mar*_*ers 5

您可以访问该r.request对象以计算传出字节,并可以通过查看content-length传入请求的标头来确定传入字节(压缩与否)。这足以满足您通常提出的所有请求的99%。

计算标头的字节大小很容易;只需将键和值的长度加起来,就将4个字节用于冒号和空格,再将2个字节用于空白行:

 def header_size(headers):
     return sum(len(key) + len(value) + 4 for key, value in headers.items()) + 2
Run Code Online (Sandbox Code Playgroud)

还有第一行;这是{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
Run Code Online (Sandbox Code Playgroud)