httplib2.Http()-TypeError:JSON对象必须为str,而不是“ bytes”

时间:2018-07-10 07:40:10

标签: python json python-3.x python-2.x httplib2

此代码在Python2中完美运行,但在Python3中不完美。我经历了很多可能的解决方案,但都没有。他们似乎工作。我该怎么做。在python3中工作?

Error.log:

[Tue Jul 10 07:23:21.713813 2018] [wsgi:error] [pid 1667:tid 140651010107136]
    h = httplib2.Http()

[Tue Jul 10 07:23:21.713843 2018] [wsgi:error] [pid 1667:tid 140651010107136]
    File "/usr/lib/python3.5/json/__init__.py", line 312, in loads

[Tue Jul 10 07:23:21.713874 2018] [wsgi:error] [pid 1667:tid 140651010107136]
    s.__class__.__name__))

[Tue Jul 10 07:23:21.713907 2018] [wsgi:error] [pid 1667:tid 140651010107136]
    TypeError: the JSON object must be str, not 'bytes'

代码:

# Check that the access token is valid.
access_token = credentials.access_token
url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s'
       % access_token)
h = httplib2.Http()
result = json.loads(h.request(url, 'GET')[1])
# If there was an error in the access token info, abort.
if result.get('error') is not None:
    response = make_response(json.dumps(result.get('error')), 500)
    response.headers['Content-Type'] = 'application/json'
    return response

2 个答案:

答案 0 :(得分:2)

the docs for the http2lib library对此进行了介绍:

  

“内容”是从URL检索到的内容。如果需要,内容已解压缩或解压缩。 “ resp”包含所有响应标头。

     

Python 3区分字节和字符串。在httplib2中,响应头是字符串,但是内容是字节。如果要将内容转换为字符串,则需要determine the character encoding,然后将其显式转换为字符串。确切的算法取决于媒体类型。 httplib2无法帮​​助您确定字符编码。

     

一旦确定了字符编码,剩下的就很容易了。例如,如果您确定编码为UTF-8,则会说:

str_content = content.decode('utf-8')

换句话说,您需要编写代码以解析HTTP标头,HTML meta标签等,以找出字符编码(以及任何回退到chardet或{{ 1}}或您想要的其他启发式库),然后Unicode, Damnit的内容,然后您可以decode的结果。


话说回来,几乎所有提供JSON服务的服务器都可能提供UTF-8或纯ASCII码以及所有非ASCII转义的内容,当然任何一种都可以解码为UTF-8。这是最新版本的3.x的默认编码,因此,如果“几乎”对您已经足够了,只需在调用json.loads之前在内容中添加一个.decode(),它就会起作用在几乎所有服务器上。


或者您可以切换到requests之类的库,该库将完成所有读取编码并为您应用编码的工作,因此您只需执行json.loads。或者甚至可以让它为您执行JSON解码,然后执行json.load(r.text)

答案 1 :(得分:1)

这对我有用。 result = json.loads((h.request(url, 'GET')[1]).decode()) 请记住,每次对代码进行编辑时都要重新加载服务器。 正如我发现的那样,它并不总是能拾起它。用它来部署在AWS Lightsail上。