使用Python检测错误的字符编码

4 投票
1 回答
3729 浏览
提问于 2025-04-16 10:11

我刚开始学习编程,最近在写一个Python程序时,发现从文件中读取到的字符串是这样的:

Îêåàí Åëüçè - Ìàéæå âåñíà
Ëÿïèñ Òðóáåöêîé - Ñâÿùåííûé Îãîíü

其实这些字符串应该是用西里尔字母写的(cp-1251编码),所以它们出现了编码错误。我经过一番搜索,终于找到了这个问题的根源,借助了这个网站:Universal Cyrillic Decoder

另外,使用chardet模块中的detect函数也能找到这个问题。

chardet.detect('Îêåàí Åëüçè - Ìàéæå âåñíà'.decode('utf-8').encode('windows-1252'))

这个函数的返回结果是:
{'confidence': 0.7679697235616183, 'encoding': 'windows-1251'}

在做了以下操作后,我成功得到了正确的字符串:

string.decode('utf-8').encode('windows-1252').decode('windows-1251').encode('utf-8')

结果是:

Океан Ельзи - Майже весна 和
Коррозия Металла - Война Миров

分别对应上面提到的字符串。

我想问的是:有没有办法检测到这样的字符串?以下是一些我还没有找到解决办法的字符串:

Isao Sasaki - ¨¬¡Æ¨¬¡ÆAI¨¬¡Æ (A Different Farewell) (¡¾¢¬Cy¨ù¡¾ AU¡Æi)
Yoon K. Lee & Salzburg Kammerp - ³»¸¶À½
⁂‭晉䤠圠牥⁥⁡潂⁹䬨牡慭牴湯捩删浥硩䴠楡⥮
��óôåõá üôé ï ã�ìïò �ôáí
ìéá áðëÃ� õðüèåóç。

非常感谢大家的回复。

1 个回答

4

这个西里尔字母的字符串并不是用cp-1251编码的。你似乎已经发现,它被“编码了两次”。很可能是有人把一个用cp1251编码的二进制字符串误认为是utf8,然后又用cp1252编码了一次,或者类似的情况。

没有任何自动检查能发现这个问题。

>>> print 'Îêåàí Åëüçè - Ìàéæå âåñíà'.decode('utf8').encode('latin1').decode('cp1251')
Океан Ельзи - Майже весна

这个方法有效。后者看起来像是UTF8,因为它支持单字节和多字节字符,但实际上它并不是UTF8。所以又是某种错误的转换发生了。要找到一个有效的组合,可能唯一的办法就是尝试所有可能的组合。

撰写回答