【发布时间】:2011-04-26 05:12:00
【问题描述】:
我正在使用
data=urllib2.urlopen(url).read()
我想知道:
如何判断 URL 中的数据是否经过 gzip 压缩?
如果数据被 gzip 压缩,urllib2 会自动解压缩数据吗?数据会一直是字符串吗?
【问题讨论】:
-
也许值得注意的是
requestslibrary 会自动处理 gzip 压缩(参见 the FAQ)
我正在使用
data=urllib2.urlopen(url).read()
我想知道:
如何判断 URL 中的数据是否经过 gzip 压缩?
如果数据被 gzip 压缩,urllib2 会自动解压缩数据吗?数据会一直是字符串吗?
【问题讨论】:
requests library 会自动处理 gzip 压缩(参见 the FAQ)
- 如何判断 URL 中的数据是否经过 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 是否会自动解压缩 gzip 后的数据?数据是否总是字符串?
没有。 urllib2 不会自动解压缩数据,因为 'Accept-Encoding' 标头不是由 urllib2 设置的,而是由您使用:request.add_header('Accept-Encoding','gzip, deflate')
【讨论】:
如果您谈论的是一个简单的.gz 文件,不,urllib2 不会对其进行解码,您将得到未更改的.gz 文件作为输出。
如果您正在谈论使用Content-Encoding: gzip 或deflate 的自动HTTP 级别压缩,那么客户端必须使用Accept-Encoding 标头故意请求。
urllib2 没有设置这个头,所以它返回的响应不会被压缩。您可以安全地获取资源而不必担心压缩(尽管由于不支持压缩,请求可能需要更长时间)。
【讨论】:
curl -vI http://en.wikipedia.org/wiki/Spanish_language |& grep '^[<>]'
您的问题已得到解答,但要获得更全面的实现,请查看 Mark Pilgrim's implementation of this,它涵盖 gzip、deflate、安全 URL 解析以及更多,对于广泛使用的 RSS 解析器,但仍然是有用的参考。
【讨论】:
现在看来 urllib3 会自动处理这个问题。
参考标题:
HTTPHeaderDict({'ETag': '"112d13e-574c64196bcd9-gzip"', '变化': '接受编码','内容编码':'gzip','X-Frame-Options': 'sameorigin', 'Server': 'Apache', 'Last-Modified': 'Sat, 01 Sep 2018 02:42:16 GMT', 'X-Content-Type-Options': 'nosniff', 'X-XSS-保护': '1;模式=块','内容类型':'文本/纯文本; charset=utf-8', '严格传输安全': 'max-age=315360000; includeSubDomains', 'X-UA-Compatible': 'IE=edge', 'Date': 'Sat, 01 Sep 2018 14:20:16 GMT”,“接受范围”:“字节”,“传输编码”: '分块'})
参考代码:
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()
【讨论】: