如何从urllib.urlopen()返回的"类文件对象"创建GzipFile实例?

Pau*_*ite 15 python gzip urllib

我正在使用Python使用Stack Overflow API.我正在尝试解码API提供的gzip压缩响应.

import urllib, gzip

url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name')
gzip.GzipFile(fileobj=url).read()
Run Code Online (Sandbox Code Playgroud)

根据urllib2文档,urlopen"返回一个类似文件的对象".

但是,当我运行read()我使用它创建的GzipFile对象时,我收到此错误:

AttributeError: addinfourl instance has no attribute 'tell'
Run Code Online (Sandbox Code Playgroud)

据我所知,这是来自返回的对象urlopen.

它似乎也没有寻求,因为当我这样做时出现错误:

url.read()
url.seek(0)
Run Code Online (Sandbox Code Playgroud)

这个对象到底是什么,以及如何GzipFile从中创建一个正常运行的实例?

ste*_*anw 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)
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法一口气读取整个`urlopen`响应的方法?我希望在urlopen的有效载荷非常大(GB)的情况下使用这种方法,因此我希望能够使用此方法在数据传入时进行流解析,而不是阻塞整个http请求。 (2认同)

unu*_*tbu 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)
Run Code Online (Sandbox Code Playgroud)

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