【问题标题】:Converting unicode characters from returned JSON in python在python中从返回的JSON转换unicode字符
【发布时间】:2013-01-15 19:09:18
【问题描述】:

我正在尝试从 musicbrainz 的 API 服务返回 JSON,一些歌曲的返回数据包含 unicode 字符,我无法将它们转换为常规符号等。请让我知道我应该在这里做什么。

JSON:

{
    "status": "ok",
    "results": [{
        "recordings": [{
            "duration": 402,
            "tracks": [{
                "duration": 402,
                "position": 6,
                "medium": {
                    "release": {
                        "id": "dde6ecee-8e9b-4b46-8c28-0f8d659f83ac",
                        "title": "Tecno Fes, Volume 2"
                    },
                    "position": 1,
                    "track_count": 11
                },
                "artists": [{
                    "id": "57c1e5ea-e08f-413a-bcb1-f4e4b675bead",
                    "name": "Gigi D\u2019Agostino"
                }],
                "title": "You Spin Me Round"
            }],
            "id": "2e0a7bce-9e44-4a63-a789-e8c4d2a12af9"
        }, ....

失败的代码(示例):

string = '\u0420\u043e\u0441\u0441\u0438\u044f'
print string.encode('utf-8')

我在 Windows 7 机器上使用它并拥有 python 2.7 并在命令行终端上运行此代码。我得到以下输出:

C:\Python27>python junk.py Gigi DGÇÖAgostino Gigi D?Agostino Gigi D\u2019Agostino

我希望输出是Gigi D' Agostino

【问题讨论】:

  • 什么是“正常”字符?
  • 我不确定您的问题到底是什么。我通过标准 JSON 解码器运行了您提供的 JSON,并且一位非 ASCII 正确地输出为“Gigi D'Agostino”。 “失败的代码”,你只是缺少一个字符。如果你写string = u'\u0420\u043e\u0441\u0441\u0438\u044f',变量被正确设置为Россия。顺便说一句,不要使用“字符串”作为变量名;它只能以泪水告终。
  • 你的意思是你需要 ASCII 编码的字符串吗?为什么?您实际上对这些数据做了什么?
  • 我在 Windows 7 机器上使用它并拥有 python 2.7 并在命令行终端上运行此代码。我得到以下输出:C:\Python27>python junk.py Gigi DGÇÖAgostino Gigi D?Agostino Gigi D\u2019Agostino
  • 我希望输出是--Gigi D' Agostino--

标签: python windows json cmd musicbrainz


【解决方案1】:

Unicode 转义仅适用于 unicode 字符串,将常规字符串转换为 unicode 使用 str.decode('unicode-escape'):

In [1]: s='\u0420\u043e\u0441\u0441\u0438\u044f'

In [2]: s
Out[2]: '\\u0420\\u043e\\u0441\\u0441\\u0438\\u044f'

In [3]: s.decode('unicode-escape')
Out[3]: u'\u0420\u043e\u0441\u0441\u0438\u044f'

In [4]: print s.decode('unicode-escape')
Россия

In [5]: s2="Gigi D\u2019Agostino"

In [6]: s2
Out[6]: 'Gigi D\\u2019Agostino'

In [7]: print s2.decode('unicode-escape')
Gigi D’Agostino

【讨论】:

  • 现在想知道这是否与我的命令行终端有关:
  • s2 = 'Gigi D\\u2019Agostino' print s2.decode('unicode-escape')



    C:\Python27>python junk.py Traceback (most recent call last): File "junk.py", line 2, in <module> print s2.decode('unicode-escape') File "C:\Python27\lib\encodings\cp437.py", line 12, in encode return codecs.charmap_encode(input,errors,encoding_map) UnicodeEncodeError: 'charmap' codec can't encode character u'\u2019' in position 6: character maps to <undefined>

  • @PremMinister -- 你是怎么运行这个的?如果您将其复制粘贴到交互式 python 解释器中,它可以工作吗?
  • .decode('unicode-escape') 对于 json-text 来说不是必需的。
  • @J.F.Sebastian -- 你当然是对的。我出于某种原因假设,由于某种原因,在使用解析器后问题仍然存在,因为“他怎么会提取字符串?”...
【解决方案2】:

您在 Windows 中使用cmd?在这种情况下,让 Unicode 正常工作以正确显示可能有点麻烦。 您可能想考虑使用另一个“终端”来测试您的脚本。 MSYS 提供了一个不错的终端/shell,IDLE 包含在 Windows Python 发行版中,并且有一个 Python Shell(右键单击,在 IDLE 中打开,F5)。

如果你真的想让它在cmd 中工作:

您必须将Lucida Console 设置为cmd 中的字体。那么:

> chcp
Active code page: 850
> chcp 65001

那么你应该在cmd 中有unicode 输出。您的“活动代码页”可能不同。请注意某处,因为您可能想在之后将其更改回来:

> chcp 850

否则会遇到其他问题(启动.bat 文件不起作用)。 (另见batch-file-encoding

在你的脚本中你还需要这个:

import codecs

def cp65001(name):
    """This might be buggy, but better than just a LookupError
    """
    if name.lower() == "cp65001":
        return codecs.lookup("utf-8")

codecs.register(cp65001)

否则python会崩溃。 (见windows-cmd-encoding-change-causes-python-crash

我的脚本有一个类似的bug report


您也可以考虑使用库来访问 MusicBrainz 网络服务。 Python-musicbrainzngs 适用于当前的 ws/2。

【讨论】:

  • 不错的文章,但除了关于 Python 中的 unicode 之外,我没有得到与此答案的联系。
  • 我得到 LookupError: unknown encoding: cp65001
  • 看来您忘记了codecs.register(cp65001) 部分。我还在示例中添加了import codecs,以明确codecs 的来源。
【解决方案3】:

您应该像任何有效的 json 解析器一样使用返回 Unicode 字符串的 json 解析器。您失败的示例显示了一个字节串,即您没有使用 json 解析器。

例如解析json数据:

obj = json.load(urllib2.urlopen(request))

在不使用 Unicode 转义的情况下漂亮地打印 obj

print json.dumps(obj, indent=4, ensure_ascii=False)

了解以下之间的区别也很有用:

print unicode_string

还有:

print repr(unicode_string)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-24
    • 2012-05-03
    • 2018-04-29
    • 1970-01-01
    • 2015-10-27
    • 2010-09-27
    • 2013-01-09
    • 2016-01-23
    相关资源
    最近更新 更多