如何从urllib.urlopen()返回的“类文件对象”创建GzipFile实例?
我正在用Python玩Stack Overflow的API。我想解码API返回的gzipped响应。
import urllib, gzip
url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name')
gzip.GzipFile(fileobj=url).read()
根据urllib2的文档,urlopen
“返回一个类似文件的对象”。
但是,当我在用它创建的GzipFile对象上运行read()
时,我遇到了这个错误:
AttributeError: addinfourl instance has no attribute 'tell'
据我所知,这个错误是由urlopen
返回的对象引起的。
它似乎也没有seek功能,因为当我尝试这样做时,我又遇到了一个错误:
url.read()
url.seek(0)
这个对象到底是什么?我该如何从它创建一个正常工作的GzipFile
实例呢?
3 个回答
0
这是对@stefanw的回答的一个新更新,可能有人觉得使用那么多内存太贵了。
感谢这篇文章(https://www.enricozini.org/blog/2011/cazzeggio/python-gzip/,它解释了为什么gzip
不起作用),解决办法是使用Python3。
import urllib.request
import gzip
response = urllib.request.urlopen('http://api.stackoverflow.com/1.0/badges/name')
with gzip.GzipFile(fileobj=response) as f:
for line in f:
print(line)
8
import urllib2
import json
import gzip
import io
url='http://api.stackoverflow.com/1.0/badges/name'
page=urllib2.urlopen(url)
gzip_filehandle=gzip.GzipFile(fileobj=io.BytesIO(page.read()))
json_data=json.loads(gzip_filehandle.read())
print(json_data)
io.BytesIO
是适用于 Python 2.6 及以上版本的。如果你使用的是更早版本的 Python,可以用 cStringIO.StringIO
来代替。
10
urlopen文档列出了返回对象支持的方法。我建议把这个对象放在另一个类里,这样可以支持gzip所需要的方法。
另一种选择是:调用响应对象的read方法,把结果放进一个StringIO对象里(这个对象应该支持gzip所需的所有方法)。不过这样可能会稍微消耗更多资源。
例如:
import gzip
import json
import StringIO
import urllib
url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name')
url_f = StringIO.StringIO(url.read())
g = gzip.GzipFile(fileobj=url_f)
j = json.load(g)