python - 如何使用 python 2.7 获取发送和接收的总字节数?

标签 python python-2.7 http urllib2

有没有一种方法可以使用 urllib2 库计算 python 2.7 应用程序中发送的总字节数和接收的总字节数?当我查看 Request 对象和响应的方法/变量时,我看不到任何方法或变量保存此值,如下所示。我检查了 urllib2 库,但是找不到我想要的。

这是我的简单例子;

#!/usr/bin/python2.7
# encoding: utf-8
from __future__ import print_function
import urllib2

req = urllib2.Request('http://example.com')
print(dir(req))
response = urllib2.urlopen(req)
print(dir(response))
the_page = response.read()
print("Length:" + str(len(the_page)))

输出是:

['_Request__fragment', '_Request__original', '__doc__', '__getattr__', '__init__', '__module__', '_tunnel_host', 'add_data', 'add_header', 'add_unredirected_header', 'data', 'get_data', 'get_full_url', 'get_header', 'get_host', 'get_method', 'get_origin_req_host', 'get_selector', 'get_type', 'has_data', 'has_header', 'has_proxy', 'header_items', 'headers', 'host', 'is_unverifiable', 'origin_req_host', 'port', 'set_proxy', 'type', 'unredirected_hdrs', 'unverifiable']
['__doc__', '__init__', '__iter__', '__module__', '__repr__', 'close', 'code', 'fileno', 'fp', 'getcode', 'geturl', 'headers', 'info', 'msg', 'next', 'read', 'readline', 'readlines', 'url']
Length:1270

Web 服务器可能会发送压缩的内容,当然简单的 len(the_page) 不足以接收总字节数。我的约束是不使用除 python2.7 下的 urllib2、urllib、httplib 以外的任何其他库来实现此目的。

如果您能帮助我们找到发送的总字节数和接收的总字节数,我们将不胜感激。

最佳答案

网络服务器不会自动压缩响应。压缩方法(gzip、deflate)取决于您的要求。

如果你想接收压缩的有效负载,你必须请求它:

req.add_header('Accept-Encoding', 'gzip')

...并且您必须自己解压缩响应。

#!/usr/bin/python2
# encoding: utf-8
from __future__ import print_function
import urllib2
import gzip
import zlib
import StringIO

req = urllib2.Request('http://www.google.com')
req.add_header('Accept-Encoding', 'gzip, deflate')
response = urllib2.urlopen(req)

the_page = response.read()
print("Length before decompression:" + str(len(the_page)))
if response.info().get('Content-Encoding') == 'gzip':
    the_page = gzip.GzipFile(fileobj=StringIO.StringIO(the_page)).read()
elif response.info().get('Content-Encoding') == 'deflate':
    the_page = zlib.decompress(the_page)

print("Length after decompression:" + str(len(the_page)))

但是无论如何...使用“len(response.read())”,您只能测量没有任何 header 的 http 有效负载的长度。

为了测量发送字节,我找到了一个 hacky 解决方案:

#!/usr/bin/python2
# encoding: utf-8
from __future__ import print_function
import urllib2
import gzip
import zlib
import StringIO
import httplib
import socket

class CountingHTTPConnection(httplib.HTTPConnection):
    bytes_sent = 0

    def __init__(self, host, port=None, strict=None,
                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None):
        self._send = self.send
        self.send = self.counting_send
        httplib.HTTPConnection.__init__(self, host, port=None, strict=None,
                                        timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None)

    def counting_send(self, data):
            CountingHTTPConnection.bytes_sent += len(data)
            self._send(data) 

class CountingHTTPHandler(urllib2.HTTPHandler):
    def http_open(self, req):
        return self.do_open(CountingHTTPConnection, req) 

req = urllib2.Request('http://www.google.com')
opener = urllib2.build_opener(CountingHTTPHandler())
req.add_header('Accept-Encoding', 'gzip, deflate')


response = opener.open(req)
the_page = response.read()
print("Length before decompression:" + str(len(the_page)))
if response.info().get('Content-Encoding') == 'gzip':
    the_page = gzip.GzipFile(fileobj=StringIO.StringIO(the_page)).read()
elif response.info().get('Content-Encoding') == 'deflate':
    the_page = zlib.decompress(the_page)

print("Length after decompression:" + str(len(the_page)))
print("bytes sent: {}".format(CountingHTTPConnection.bytes_sent))

...请注意,上面的代码仅适用于 http 连接。

关于python - 如何使用 python 2.7 获取发送和接收的总字节数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33031719/

相关文章:

python - 使接受另一个函数参数超集的函数的函数调用签名保持一致

google-app-engine - Google App Engine 上 Jinja2 中的千位分隔符错误

http - Angular 2 http delete 不发出网络请求

java - http OAuth 响应错误

javascript - AngularJs $http.get : Sending array of objects as params

python - fabric 和 svn 密码

python - Scikit 线性模型何时返回分数负值?

python - Pandas : adding a column to pivot and filtering

python - 什么时候应该使用内存 View ?

python - 为什么在 python 2.7 和 python 3.4 性能中创建类之间存在差异