Python 如何从“;类文件对象”;urllib.urlopen()返回了什么?

Python 如何从“;类文件对象”;urllib.urlopen()返回了什么?,python,gzip,urllib,Python,Gzip,Urllib,我正在使用Python处理堆栈溢出API。我试图解码API给出的gzip响应 import urllib, gzip url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name') gzip.GzipFile(fileobj=url).read() 根据,urlopen“返回类似文件的对象” 但是,当我在使用它创建的gzip文件对象上运行read()时,会出现以下错误: AttributeError: addinfou

我正在使用Python处理堆栈溢出API。我试图解码API给出的gzip响应

import urllib, gzip

url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name')
gzip.GzipFile(fileobj=url).read()
根据,
urlopen
“返回类似文件的对象”

但是,当我在使用它创建的gzip文件对象上运行
read()
时,会出现以下错误:

AttributeError: addinfourl instance has no attribute 'tell'
据我所知,这是来自
urlopen
返回的对象

它似乎也没有seek,因为我执行此操作时出错:

url.read()
url.seek(0)
这个对象到底是什么,如何从中创建一个正常运行的
gzip文件
实例?

返回的对象支持的方法列表。我建议将对象包装到另一个类中,该类支持gzip所期望的方法

其他选项:调用response对象的read方法并将结果放入一个对象中(该对象应支持gzip期望的所有方法)。不过这可能会贵一点

例如


io.BytesIO
用于Python2.6+。对于较旧版本的Python,您可以使用
cStringIO.StringIO

这里是@stefanw答案的一个新更新,对他来说,使用这么多内存可能太贵了

感谢这篇文章(它解释了为什么
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)

将其包装在
StringIO
对象中可以克服该错误,但我仍然得到一个
IOError:不是一个gzip文件
@ThomasK,它可以为我找到。您是将
url.read()
传递给
StringIO
构造函数还是只传递
url
?后者失败了。太好了,干杯。Unutbu的回答也很好,但我会选择这个,因为我猜
StringIO
解决方案更向后兼容。有没有一种方法可以做到这一点,而不必一次性阅读整个
urlopen
响应?我希望在
urlopen
的负载非常大(GBs)的情况下使用类似的方法,因此我希望能够在数据进入时使用它来流解析,而不是阻塞整个http请求。
内容编码:gzip
应该由http库处理,但不幸的是,它不是。这是Python的bug数据库,供感兴趣的人使用。@Magnus:干杯,很高兴知道它至少在bug跟踪器中。
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)
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)