python urllib2会自动解压缩从网页获取的gzip数据吗?

时间:2010-10-16 00:45:49

标签: python gzip urllib2

我正在使用

 data=urllib2.urlopen(url).read()

我想知道:

  1. 如何判断网址上的数据是否已被gzip压缩?

  2. 如果数据被压缩,urllib2会自动解压缩数据吗?数据总是一个字符串吗?

4 个答案:

答案 0 :(得分:145)

  
      
  1. 如何判断URL中的数据是否已被gzip压缩?
  2.   

这会检查内容是否经过gzip压缩并解压缩:

from StringIO import StringIO
import gzip

request = urllib2.Request('http://example.com/')
request.add_header('Accept-encoding', 'gzip')
response = urllib2.urlopen(request)
if response.info().get('Content-Encoding') == 'gzip':
    buf = StringIO(response.read())
    f = gzip.GzipFile(fileobj=buf)
    data = f.read()
  
      
  1. 如果数据被压缩,urllib2会自动解压缩数据吗?数据总是一个字符串吗?
  2.   

没有。 urllib2不会自动解压缩数据,因为urllib2并未设置'Accept-Encoding'标头,而是由您使用:request.add_header('Accept-Encoding','gzip, deflate')

答案 1 :(得分:7)

如果您正在谈论一个简单的.gz文件,不,urllib2不会对其进行解码,您将获得未更改的.gz文件作为输出。

如果您正在讨论使用Content-Encoding: gzipdeflate进行自动HTTP级别压缩,那么客户端必须使用Accept-Encoding标头请求它。

urllib2没有设置此标头,因此不会压缩它返回的响应。您可以安全地获取资源而无需担心压缩(尽管由于不支持压缩,请求可能需要更长时间)。

答案 2 :(得分:5)

您的问题已得到解答,但是为了更全面的实施,请查看Mark Pilgrim's implementation of this,它涵盖了广泛使用的RSS解析器的gzip,deflate,安全URL解析以及更多内容,但是然而,这是一个有用的参考。

答案 3 :(得分:0)

看来urllib3现在自动处理此问题。

参考标题:

  

HTTPHeaderDict({'ETag':'“ 112d13e-574c64196bcd9-gzip”','Vary':   '接受编码','内容编码':'gzip','X框架选项':   'sameorigin','Server':'Apache','Last-Modified':'Sat,01 Sep 2018   02:42:16 GMT”,“ X内容类型选项”:“ nosniff”,   'X-XSS-Protection':'1; mode = block”,“ Content-Type”:“ text / plain;   charset = utf-8',“严格运输安全性”:“ max-age = 315360000;   includeSubDomains”,“与X-UA兼容”:“ IE = edge”,“日期”:“星期六,9月1日”   2018 14:20:16 GMT'',``接受范围'':``字节'',``传输编码'':   'chunked'})

参考代码:

import gzip
import io
import urllib3

class EDDBMultiDataFetcher():
    def __init__(self):
        self.files_dict = {
            'Populated Systems':'http://eddb.io/archive/v5/systems_populated.jsonl',
            'Stations':'http://eddb.io/archive/v5/stations.jsonl',
            'Minor factions':'http://eddb.io/archive/v5/factions.jsonl',
            'Commodities':'http://eddb.io/archive/v5/commodities.json'
            }
        self.http = urllib3.PoolManager()
    def fetch_all(self):
        for item, url in self.files_dict.items():
            self.fetch(item, url)

    def fetch(self, item, url, save_file = None):
        print("Fetching: " + item)
        request = self.http.request(
            'GET',
            url,
            headers={
                'Accept-encoding': 'gzip, deflate, sdch'
                })
        data = request.data.decode('utf-8')
        print("Fetch complete")
        print(data)
        print(request.headers)
        quit()


if __name__ == '__main__':
    print("Fetching files from eddb.io")
    fetcher = EDDBMultiDataFetcher()
    fetcher.fetch_all()