python2
から3
にコードを移植しているときに、URLから読み取るときにこのエラーが発生します
TypeError:initial_valueは、バイトではなくstrまたはNoneでなければなりません。
import urllib
import json
import gzip
from urllib.parse import urlencode
from urllib.request import Request
service_url = 'https://babelfy.io/v1/disambiguate'
text = 'BabelNet is both a multilingual encyclopedic dictionary and a semantic network'
lang = 'EN'
Key = 'KEY'
params = {
'text' : text,
'key' : Key,
'lang' :'EN'
}
url = service_url + '?' + urllib.urlencode(params)
request = Request(url)
request.add_header('Accept-encoding', 'gzip')
response = urllib.request.urlopen(request)
if response.info().get('Content-Encoding') == 'gzip':
buf = StringIO(response.read())
f = gzip.GzipFile(fileobj=buf)
data = json.loads(f.read())
この行で例外がスローされます
buf = StringIO(response.read())
Python2を使用すると、問題なく動作します。
response.read()
はbytes
のインスタンスを返しますが、 StringIO
はテキスト専用のメモリ内ストリームです。代わりに BytesIO
を使用してください。
から Python 3.0-Unicode Vs. 8ビットではなくテキストVs.データ)の新機能
StringIO
およびcStringIO
モジュールはなくなりました。代わりに、io
モジュールをインポートし、io.StringIO
またはio.BytesIO
はそれぞれテキストとデータ用です。
これは別のpython3 bytes
対str
問題のように見えます。応答はbytes
型(python 3とstr
で異なる)です。最初にresponse.read().decode('utf-8')
と言ってからStringIO
を使用するか、誰かが言ったようにBytesIO
を使用することもできますが、str
であると予想される場合は、decode
を最初にstr
に入れます。
Io.StringIOの代わりにsix.StringIOの使用を検討してください。