关于python:让JSON对象接受字节或让urlopen输出字符串

Let JSON object accept bytes or let urlopen output strings

使用python 3,我从一个URL请求一个JSON文档。

1
response = urllib.request.urlopen(request)

response对象是一个文件类对象,使用readreadline方法。通常,JSON对象可以通过以文本模式打开的文件来创建。

1
obj = json.load(fp)

我想做的是:

1
obj = json.load(response)

但是,这不起作用,因为urlopen以二进制模式返回文件对象。

当然,解决问题的方法是:

1
2
str_response = response.read().decode('utf-8')
obj = json.loads(str_response)

但这感觉很糟糕…

是否有更好的方法可以将字节文件对象转换为字符串文件对象?或者,我是否缺少用于urlopenjson.load进行编码的任何参数?


Python神奇的标准库来拯救…

1
2
3
4
import codecs

reader = codecs.getreader("utf-8")
obj = json.load(reader(response))

与PY2和PY3一起使用。

文档:python 2,python3


HTTP发送字节。如果所讨论的资源是文本,则通常通过内容类型HTTP头或其他机制(RFC、HTML meta http-equiv…)指定字符编码。

urllib应该知道如何将字节编码为字符串,但它太小了?这是一个非常缺乏动力的非Python图书馆。

深入了解python 3提供了有关情况的概述。

你的"周围工作"虽然感觉不对,但它是正确的方法。


我认为这个问题是最好的答案:)

1
2
3
4
5
import json
from urllib.request import urlopen

response = urlopen("site.com/api/foo/bar").read().decode('utf8')
obj = json.loads(response)

对于使用requests库解决此问题的任何其他人:

1
2
3
4
5
6
7
import json
import requests

r = requests.get('http://localhost/index.json')
r.raise_for_status()
# works for Python2 and Python3
json.loads(r.content.decode('utf-8'))


这个对我有用,我和json()一起使用了"请求"库,在"人类请求"中查看文档。

1
2
3
4
5
import requests

url = 'here goes your url'

obj = requests.get(url).json()

我使用python 3.4.3&3.5.2和django 1.11.3遇到了类似的问题。但是,当我升级到python 3.6.1时,问题就消失了。

您可以在这里阅读更多信息:https://docs.python.org/3/whatsnew/3.6.html_json

如果您没有绑定到特定版本的Python,只需考虑升级到3.6或更高版本。


如果您在使用烧瓶微框架时遇到此问题,那么您只需执行以下操作:

data = json.loads(response.get_data(as_text=True))

来自文档:"如果as_text设置为true,则返回值将是解码后的Unicode字符串。"


你的解决方法实际上救了我。我在使用Falcon框架处理请求时遇到了很多问题。这对我很有用。req是curl pr httpie请求表

1
json.loads(req.stream.read().decode('utf-8'))

刚刚发现了这个简单的方法,可以将httpresponse内容作为JSON

1
2
3
4
5
6
7
8
9
10
11
import json

request = RequestFactory() # ignore this, this just like your request object

response = MyView.as_view()(request) # got response as HttpResponse object

response.render() # call this so we could call response.content after

json_response = json.loads(response.content.decode('utf-8'))

print(json_response) # {"your_json_key":"your json value"}

希望能帮到你


这将把字节数据流化到JSON中。

1
2
3
import io

obj = json.load(io.TextIOWrapper(response))

相对于编解码器的模块阅读器,IO.textIOwrapper是首选。https://www.python.org/dev/peps/pep-0400/


我用下面的程序来使用json.loads()

1
2
3
4
5
6
7
8
9
10
11
import urllib.request
import json
endpoint = 'https://maps.googleapis.com/maps/api/directions/json?'
api_key = 'AIzaSyABbKiwfzv9vLBR_kCuhO7w13Kseu68lr0'
origin = input('where are you ?').replace(' ','+')
destination = input('where do u want to go').replace(' ','+')
nav_request = 'origin={}&destination={}&key={}'.format(origin,destination,api_key)
request = endpoint + nav_request
**response = urllib.request.urlopen(request).read().decode('utf-8')
directions = json.loads(response)**
print(directions)