让 JSON 对象接受字节或让 urlopen 输出字符串
使用 Python 3,我从 URL 请求 json 文档。
response = urllib.request.urlopen(request)
response
对象是一个类似文件的对象,具有 read
和 readline
方法。通常,可以使用以文本模式打开的文件来创建 JSON 对象。
obj = json.load(fp)
我想做的是:
obj = json.load(response)
但这不起作用,因为 urlopen 以二进制模式返回文件对象。
当然,解决方法是:
str_response = response.read().decode('utf-8')
obj = json.loads(str_response)
但这感觉很糟糕......
有没有更好的方法可以将字节文件对象转换为字符串文件对象?或者我是否缺少 urlopen
或 json.load
的任何参数来提供编码?
With Python 3 I am requesting a json document from a URL.
response = urllib.request.urlopen(request)
The response
object is a file-like object with read
and readline
methods. Normally a JSON object can be created with a file opened in text mode.
obj = json.load(fp)
What I would like to do is:
obj = json.load(response)
This however does not work as urlopen returns a file object in binary mode.
A work around is of course:
str_response = response.read().decode('utf-8')
obj = json.loads(str_response)
but this feels bad...
Is there a better way that I can transform a bytes file object to a string file object? Or am I missing any parameters for either urlopen
or json.load
to give an encoding?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
Python 出色的标准库可以拯救您……
适用于 py2 和 py3。
文档:Python 2、Python3
Python’s wonderful standard library to the rescue…
Works with both py2 and py3.
Docs: Python 2, Python3
HTTP 发送字节。如果相关资源是文本,则通常通过 Content-Type HTTP 标头或其他机制(RFC、HTML
meta http-equiv
...)指定字符编码。urllib
应该知道如何将字节编码为字符串,但它太天真了——它是一个功能严重不足且非Pythonic的库。深入了解 Python 3 提供了概述关于情况。
你的“解决方法”很好——虽然感觉不对,但这是正确的方法。
HTTP sends bytes. If the resource in question is text, the character encoding is normally specified, either by the Content-Type HTTP header or by another mechanism (an RFC, HTML
meta http-equiv
,...).urllib
should know how to encode the bytes to a string, but it's too naïve—it's a horribly underpowered and un-Pythonic library.Dive Into Python 3 provides an overview about the situation.
Your "work-around" is fine—although it feels wrong, it's the correct way to do it.
我认为这个问题是最好的答案:)
I have come to opinion that the question is the best answer :)
对于尝试使用
requests
库解决此问题的其他人:For anyone else trying to solve this using the
requests
library:这个对我有用,我使用了 'request' 库和
json()
查看 对人类的请求This one works for me, I used 'request' library with
json()
check out the doc in requests for humans我使用 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 或更高版本。
I ran into similar problems using Python 3.4.3 & 3.5.2 and Django 1.11.3. However, when I upgraded to Python 3.6.1 the problems went away.
You can read more about it here:
https://docs.python.org/3/whatsnew/3.6.html#json
If you're not tied to a specific version of Python, just consider upgrading to 3.6 or later.
从 Python 3.6 开始,您可以使用
json.loads()< /code>
直接反序列化
bytes
对象(编码必须是UTF-8、UTF-16或UTF-32)。因此,仅使用标准库中的模块,您可以执行以下操作:As of Python 3.6, you can use
json.loads()
to deserialize abytes
object directly (the encoding must be UTF-8, UTF-16 or UTF-32). So, using only modules from the standard library, you can do:如果您在使用 Flask 微框架时遇到此问题,那么您可以执行以下操作:
data = json.loads(response.get_data(as_text=True))
来自文档:“如果as_text 设置为 True 返回值将是解码后的 unicode 字符串”
If you're experiencing this issue whilst using the flask microframework, then you can just do:
data = json.loads(response.get_data(as_text=True))
From the docs: "If as_text is set to True the return value will be a decoded unicode string"
这会将字节数据流式传输到 json 中。
io.TextIOWrapper
优先于codecs
模块阅读器。 https://www.python.org/dev/peps/pep-0400/< /a>This will stream the byte data into json.
io.TextIOWrapper
is preferred to thecodecs
module reader. https://www.python.org/dev/peps/pep-0400/你的解决方法实际上救了我。我在使用 Falcon 框架处理请求时遇到了很多问题。这对我有用。 req 是请求形式curl pr httpie
Your workaround actually just saved me. I was having a lot of problems processing the request using the Falcon framework. This worked for me. req being the request form curl pr httpie
刚刚发现这个简单的方法将
HttpResponse
内容作为 json 返回:希望对您有帮助。
Just found this simple method to return
HttpResponse
content as a json:Hope that helps you.
我使用下面的程序来使用 json.loads()
I used below program to use of
json.loads()