我正在使用
data=urllib2.urlopen(url).read()
我想知道:
- 如何判断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')
如果你在谈论一个简单的.gz
文件,不,urllib2将不解码它,你将获得未更改的.gz
文件作为输出。
如果您正在讨论使用Content-Encoding: gzip
或deflate
进行自动HTTP级别压缩,那么必须由客户端使用Accept-Encoding
标头进行故意请求。
urllib2不设置此标头,因此不会压缩它返回的响应。您可以安全地获取资源而无需担心压缩(尽管由于不支持压缩,请求可能需要更长时间)。
您的问题已得到解答,但是为了更全面的实现,请查看Mark Pilgrim's implementation of this,它涵盖gzip,deflate,安全URL解析以及更多,对于广泛使用的RSS解析器,但仍然是一个有用的参考。
看来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()