Python3错误:initial_value必须是str或None

时间:2015-06-26 04:33:16

标签: python python-3.x urllib2 urllib

将代码从python2移植到3时,从网址读取时出现此错误

  

TypeError:initial_value必须是str或None,而不是bytes。

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,它可以正常工作。

3 个答案:

答案 0 :(得分:68)

response.read()返回bytes的实例,而StringIO是仅用于文本的内存中的流。请改用BytesIO

来自What's new in Python 3.0 - Text Vs. Data Instead Of Unicode Vs. 8-bit

  

StringIOcStringIO模块已不复存在。相反,请导入io模块并分别使用io.StringIOio.BytesIO获取文本和数据。

答案 1 :(得分:14)

这看起来像另一个python3 bytesstr问题。您的响应类型为bytes(在python 3中与str不同)。您需要首先使用response.read().decode('utf-8')说明将其变为字符串,然后在其上使用StringIO。或者,您可能希望使用BytesIO,但如果您希望它是str,则首选decode进入str

答案 2 :(得分:0)

考虑使用six.StringIO而不是io.StringIO。