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



这段代码在Python2中运行良好,但在Python3中则不然。我想了很多可能的解决方案,但都没有。它们似乎起作用了。我该怎么做。穿着蟒蛇工作?

错误日志:

[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

这在http2lib库的文档中有介绍:

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

Python3区分了字节和字符串。在httplib2中,响应头是字符串,但内容是字节。如果要将内容转换为字符串,则需要确定字符编码,然后显式地将其转换为字符串。这样做的确切算法取决于媒体类型;httplib2无法帮助您确定字符编码。

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

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

换言之,您需要编写代码来解析HTTP标头、HTMLmeta标记等,以确定字符编码(加上对chardetUnicode, Damnit或其他所需启发式库的任何回退(,然后decode内容,然后可以json.loads结果。


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


或者您可以切换到像requests这样的库,它为您完成读取编码并应用它的所有工作,所以您可以只执行json.load(r.text)。或者,您甚至可以让它为您进行JSON解码,并执行r.json()

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

相关内容

最新更新