我正在使用
data=urllib2.urlopen(url).read()
我想知道:
如何判断网址上的数据是否已被gzip压缩?
如果数据被压缩,urllib2会自动解压缩数据吗?数据总是一个字符串吗?
答案 0 :(得分:145)
- 如何判断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()
- 如果数据被压缩,urllib2会自动解压缩数据吗?数据总是一个字符串吗?
醇>
没有。 urllib2不会自动解压缩数据,因为urllib2并未设置'Accept-Encoding'标头,而是由您使用:request.add_header('Accept-Encoding','gzip, deflate')
答案 1 :(得分:7)
如果您正在谈论一个简单的.gz
文件,不,urllib2不会对其进行解码,您将获得未更改的.gz
文件作为输出。
如果您正在讨论使用Content-Encoding: gzip
或deflate
进行自动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()