我正在尝试解析包含一些芬兰字符的json。一个goog例子是一个名为Etelä-Karjala的地区。当我打开json作为文件然后加载json.load时,我把它全部工作在本地。我为这个地区获得的unicode是u'Etel \ xe4-Karjala'。
然而,我的下一步是在服务器上做同样的事情,并且json存储在我必须从中检索它的一些URL。我使用了json.loads(requests.get(url).text),而我在同一地区获得的unicode现在是u'Etel \ xc3 \ xa4-Karjala'。
即使输入文件相同,为什么我会得到这些不同的结果?你能建议一个变通方法或一个好的模式从一个不会导致这个问题的网址加载json吗?
以下是重现此问题的示例:
import requests
import json
# Example with loading from request
r = requests.get('http://becs.aalto.fi/~smirnod1/maakunnat.geojson')
geo1 = json.loads(r.text)
test1 = geo1['features'][5]['properties']['text']
# test1 = u'Etel\xc3\xa4-Karjala'
然后,我下载这个json并尝试将其作为文件打开(这是我在开发应用程序时使用的方法)。
# Example with loading from file
with open('/Users/dmitrysmirnov/Downloads/maakunnat.geojson') as f:
geo2 = json.load(f)
test2 = geo2['features'][5]['properties']['text']
# test2 = u'Etel\xe4-Karjala'
我认为u'Etel \ xe4-Karjala'(或test2的结果)应该是我的目标。或者至少这是不会破坏应用程序的结果。
答案 0 :(得分:2)
服务器配置错误。要么告诉它报告该文件被编码为UTF-8,要么只用ASCII编码JSON。
答案 1 :(得分:2)
json.loads(r.text)
r.text
是requests
模块从字节解码到unicode的响应内容。由于缺少来自服务器的字符集信息,requests
已经猜到文件内容可能是ISO-8859-1编码。
requests
在这种情况下是错误的,因为实际上内容是JSON,它有自己的确定编码的机制,即默认情况下它是UTF-8。
如果将响应的原始字节直接提供给JSON解析器,它将使用其对JSON编码规则的了解来正确加载数据:
json.loads(r.content)
通常,text/...
参数的charset=
媒体类型最好在requests
图层中解码(使用.text
),这可以自动注意该参数。但是像JSON这样的application/...
类型有自己的带内信令编码规则,因此字节应该传递给这些类型的解析器,而不是在requests
中解码。