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

问题描述 投票:68回答:4

我正在使用

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

我想知道:

  1. 如何判断URL中的数据是否被gzip压缩?
  2. 如果数据被压缩,urllib2会自动解压缩数据吗?数据总是一个字符串吗?
python gzip urllib2
4个回答
145
投票
  1. 如何判断URL中的数据是否被gzip压缩?

这将检查内容是否经过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会自动解压缩数据吗?数据总是一个字符串吗?

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


7
投票

如果你在谈论一个简单的.gz文件,不,urllib2将不解码它,你将获得未更改的.gz文件作为输出。

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

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


5
投票

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


0
投票

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

参考标题:

HTTPHeaderDict({'ETag':'“112d13e-574c64196bcd9-gzip”','Vary':'Accept-Encoding','Content-Encoding':'gzip','X-Frame-Options':'sameorigin',' Server':'Apache','Last-Modified':'Sat,01 Sep 2018 02:42:16 GMT','X-Content-Type-Options':'nosniff','X-XSS-Protection':' 1; mode = block','Content-Type':'text / plain; charset = utf-8','Strict-Transport-Security':'max-age = 315360000; includeSubDomains','X-UA-Compatible' :'IE = edge','Date':'Sat,01 Sep 2018 14:20:16 GMT','Accept-Ranges':'bytes','Transfer-Encoding':'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()
© www.soinside.com 2019 - 2024. All rights reserved.