簡體   English   中英

如何從urllib.urlopen()返回的“類文件對象”創建GzipFile實例?

[英]How can I create a GzipFile instance from the “file-like object” that urllib.urlopen() returns?

我正在使用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()

根據urllib2文檔urlopen “返回一個類似文件的對象”。

但是,當我在使用它創建的GzipFile對象上運行read()時,我收到此錯誤:

AttributeError: addinfourl instance has no attribute 'tell'

據我所知,這是來自urlopen返回的對象。

它似乎也沒有尋求,因為當我這樣做時出現錯誤:

url.read()
url.seek(0)

這個對象到底是什么,以及如何GzipFile創建一個正常運行的GzipFile實例?

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)
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適用於Python2.6 +。 對於舊版本的Python,您可以使用cStringIO.StringIO

這是@ 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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM