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

时间:2015-10-09 06:51:27

标签: 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)对于接收的总字节数不够。我的约束是不要使用除pyll2.7下的urllib2,urllib,httplib之外的任何其他库来实现这一点。

可以获得任何帮助以查找总发送字节数和总接收字节数。

2 个答案:

答案 0 :(得分:3)

网络服务器不会自动压缩响应。压缩方法(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())”你只测量没有任何标题的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连接。

答案 1 :(得分:0)

您可以使用

result = urllib2.urlopen('http://www.example.com')
print result.headers['content-length']

实际上等于

result = urllib2.urlopen('http://www.example.com')
print len(result.read())

表示您收到的字节数不超过您请求的页面中的字符数。

相关问题