Kev*_*lan 6 python encoding utf-8 mojibake
我有一个可能不正确编码的json文档来自我无法控制的源,它包含以下字符串:
d\u00c3\u00a9cor
business\u00e2\u20ac\u2122 active accounts
the \u00e2\u20ac\u0153Made in the USA\u00e2\u20ac\u009d label
Run Code Online (Sandbox Code Playgroud)
从此,我正在聚集他们打算\u00c3\u00a9beceom é,这将是utf-8十六进制C3 A9.这有点道理.对于其他人,我假设我们正在处理某些类型的方向引号.
我的理论是,这要么使用我之前从未遇到过的编码,要么是以某种方式进行了双重编码.我很好地编写了一些代码来将他们破碎的输入转换成我能理解的东西,因为如果我把它引起他们的注意,他们很可能无法修复系统.
任何想法如何强迫他们的输入我能理解的东西?为了记录,我正在使用Python.
Ned*_*der 13
你应该尝试ftfy模块:
>>> print ftfy.ftfy(u"d\u00c3\u00a9cor")
décor
>>> print ftfy.ftfy(u"business\u00e2\u20ac\u2122 active accounts")
business' active accounts
>>> print ftfy.ftfy(u"the \u00e2\u20ac\u0153Made in the USA\u00e2\u20ac\u009d label")
the "Made in the USA" label
>>> print ftfy.ftfy(u"the \u00e2\u20ac\u0153Made in the USA\u00e2\u20ac\u009d label", uncurl_quotes=False)
the “Made in the USA” label
Run Code Online (Sandbox Code Playgroud)
你有Mojibake数据 ; UTF-8数据使用错误的编解码器从字节解码.
关键是要弄清楚其编码被用于解码,产生JSON输出之前.如果您认为编码是Windows代码页1252,则可以修复前两个样本:
>>> sample = u'''\
... d\u00c3\u00a9cor
... business\u00e2\u20ac\u2122 active accounts
... the \u00e2\u20ac\u0153Made in the USA\u00e2\u20ac\u009d label
... '''.splitlines()
>>> print sample[0].encode('cp1252').decode('utf8')
décor
>>> print sample[1].encode('cp1252').decode('utf8')
business’ active accounts
Run Code Online (Sandbox Code Playgroud)
但是这个编解码器在第3次失败了:
>>> print sample[2].encode('cp1252').decode('utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/encodings/cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\x9d' in position 24: character maps to <undefined>
Run Code Online (Sandbox Code Playgroud)
对于U + 201C LEFT DOUBLE QUOTATION MARK代码点,前3个'奇怪'字节肯定是CP1252 Mojibake :
>>> sample[2]
u'the \xe2\u20ac\u0153Made in the USA\xe2\u20ac\x9d label'
>>> sample[2][:22].encode('cp1252').decode('utf8')
u'the \u201cMade in the USA'
Run Code Online (Sandbox Code Playgroud)
所以另一个组合可能是U + 201D右双引号,但后一个字符导致CP1252中通常不存在UTF-8字节:
>>> u'\u201d'.encode('utf8').decode('cp1252')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/encodings/cp1252.py", line 15, in decode
return codecs.charmap_decode(input,errors,decoding_table)
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 2: character maps to <undefined>
Run Code Online (Sandbox Code Playgroud)
这是因为CP1252编解码器中没有十六进制9D位置,但是代码点确实使其成为JSON输出:
>>> sample[2][22:]
u'\xe2\u20ac\x9d label'
Run Code Online (Sandbox Code Playgroud)
该ftfy图书馆内德尔德这样有益提醒我采用了"马虎" CP1252编解码器来解决这一问题,映射不存在的字节一个一对一(UTF-8字节的Latin-1的Unicode点).然后,库中将生成的"花哨引号"映射到ASCII引号,但您可以将其关闭:
>>> import ftfy
>>> ftfy.fix_text(sample[2])
u'the "Made in the USA" label'
>>> ftfy.fix_text(sample[2], uncurl_quotes=False)
u'the \u201cMade in the USA\u201d label'
Run Code Online (Sandbox Code Playgroud)
由于这个库可以为您自动执行此任务,并且比标准Python编解码器在这里为您做的更好,您应该只安装它,并将其应用到此API提供给您的混乱中.但是,如果你有一半的机会,请不要犹豫,责备那些提供这些数据的人.他们制作了一个可爱的笨蛋.
| 归档时间: |
|
| 查看次数: |
3432 次 |
| 最近记录: |