我正在使用
data=urllib2.urlopen(url).read()
我想知道:
如何判断URL上的数据是否已压缩?
如果将urllib2压缩,数据是否会自动解压缩?数据将始终是字符串吗?
Answers:
- 如何判断URL上的数据是否已压缩?
这将检查内容是否被压缩并解压缩:
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
或进行HTTP级别的自动压缩deflate
,那么客户端必须使用Accept-Encoding
标头有意地请求该压缩。
urllib2未设置此标头,因此不会压缩返回的响应。您可以安全地获取资源,而不必担心压缩(尽管由于不支持压缩,所以请求可能需要更长的时间)。
curl -vI http://en.wikipedia.org/wiki/Spanish_language |& grep '^[<>]'
您的问题已得到解答,但是对于更全面的实现,请看一下Mark Pilgrim的this的实现,它涵盖了gzip,deflate,安全的URL解析等,并且对于一个广泛使用的RSS解析器而言,还有很多,但仍然是有用的参考。
看来urllib3现在自动处理此问题。
参考标题:
HTTPHeaderDict({'ETag':'“ 112d13e-574c64196bcd9-gzip”','Vary':'Accept-Encoding','Content-Encoding':'gzip','X-Frame-Options':'sameorigin','服务器'':'Apache','上次修改时间':'星期六,2018年9月1日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()
requests
库会自动处理gzip压缩(请参阅FAQ)