让 JSON 对象接受字节或让 urlopen 输出字符串

发布于 2024-11-26 23:31:28 字数 627 浏览 3 评论 0原文

使用 Python 3,我从 URL 请求 json 文档。

response = urllib.request.urlopen(request)

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

obj = json.load(fp)

我想做的是:

obj = json.load(response)

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

当然,解决方法是:

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

但这感觉很糟糕......

有没有更好的方法可以将字节文件对象转换为字符串文件对象?或者我是否缺少 urlopenjson.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

热情消退 2024-12-03 23:31:28

Python 出色的标准库可以拯救您……

import codecs

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

适用于 py2 和 py3。

文档:Python 2Python3

Python’s wonderful standard library to the rescue…

import codecs

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

Works with both py2 and py3.

Docs: Python 2, Python3

热风软妹 2024-12-03 23:31:28

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.

夜声 2024-12-03 23:31:28

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

import json
from urllib.request import urlopen

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

I have come to opinion that the question is the best answer :)

import json
from urllib.request import urlopen

response = urlopen("site.com/api/foo/bar").read().decode('utf8')
obj = json.loads(response)
长安忆 2024-12-03 23:31:28

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

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'))

For anyone else trying to solve this using the requests library:

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'))
沉溺在你眼里的海 2024-12-03 23:31:28

这个对我有用,我使用了 'request' 库和 json() 查看 对人类的请求

import requests

url = 'here goes your url'

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

This one works for me, I used 'request' library with json() check out the doc in requests for humans

import requests

url = 'here goes your url'

obj = requests.get(url).json() 
谜兔 2024-12-03 23:31:28

我使用 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.

人│生佛魔见 2024-12-03 23:31:28

从 Python 3.6 开始,您可以使用 json.loads()< /code>直接反序列化bytes对象(编码必须是UTF-8、UTF-16或UTF-32)。因此,仅使用标准库中的模块,您可以执行以下操作:

import json
from urllib import request

response = request.urlopen(url).read()
data = json.loads(response)

As of Python 3.6, you can use json.loads() to deserialize a bytesobject directly (the encoding must be UTF-8, UTF-16 or UTF-32). So, using only modules from the standard library, you can do:

import json
from urllib import request

response = request.urlopen(url).read()
data = json.loads(response)
一抹微笑 2024-12-03 23:31:28

如果您在使用 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"

还在原地等你 2024-12-03 23:31:28

这会将字节数据流式传输到 json 中。

import io

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

io.TextIOWrapper 优先于 codecs 模块阅读器。 https://www.python.org/dev/peps/pep-0400/< /a>

This will stream the byte data into json.

import io

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

io.TextIOWrapper is preferred to the codecs module reader. https://www.python.org/dev/peps/pep-0400/

听闻余生 2024-12-03 23:31:28

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

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

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

json.loads(req.stream.read().decode('utf-8'))
梦在深巷 2024-12-03 23:31:28

刚刚发现这个简单的方法将 HttpResponse 内容作为 json 返回:

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"}

希望对您有帮助。

Just found this simple method to return HttpResponse content as a json:

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"}

Hope that helps you.

懷念過去 2024-12-03 23:31:28

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

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)

I used below program to use of json.loads()

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文