Python 用蟒蛇和诱变剂进行脱毛

Python 用蟒蛇和诱变剂进行脱毛,python,unicode,encoding,mojibake,mutagen,Python,Unicode,Encoding,Mojibake,Mutagen,我正在读带有诱变剂的莫吉巴基ID3标签。我的目标是修复mojibake,同时学习编码和Python对其的处理 我正在处理的文件有一个ID3v2标记,我正在查看它的相册(TALB)帧,这是根据TALBID3帧中的编码字节,用拉丁语-1(ISO-8859-1)编码的。我知道这个帧中的字节是用cp1251(西里尔文)编码的 以下是我目前的代码: >>> from mutagen.mp3 import MP3 >>> mp3 = MP3(paths[0]) &g

我正在读带有诱变剂的莫吉巴基ID3标签。我的目标是修复mojibake,同时学习编码和Python对其的处理

我正在处理的文件有一个
ID3v2
标记,我正在查看它的相册(
TALB
)帧,这是根据
TALB
ID3帧中的编码字节,用拉丁语-1(
ISO-8859-1
)编码的。我知道这个帧中的字节是用
cp1251
(西里尔文)编码的

以下是我目前的代码:

 >>> from mutagen.mp3 import MP3
 >>> mp3 = MP3(paths[0])
 >>> mp3['TALB']
 TALB(encoding=0, text=[u'\xc1\xf3\xf0\xe6\xf3\xe9\xf1\xea\xe8\xe5 \xef\xeb\xff\xf1\xea\xe8'])
现在,如您所见,
mp3['TALB'].text[0]
在这里表示为Unicode字符串。然而,这是莫吉巴的:

 >>> print mp3['TALB'].text[0]
 Áóðæóéñêèå ïëÿñêè
在将这些
cp1251
字节转换为正确的Unicode码点方面,我运气很差。到目前为止,我最好的成绩非常不相称:

>>> st = ''.join([chr(ord(x)) for x in mp3['TALB'].text[0]]); st
'\xc1\xf3\xf0\xe6\xf3\xe9\xf1\xea\xe8\xe5 \xef\xeb\xff\xf1\xea\xe8'
>>> print st.decode('cp1251')
Буржуйские пляски <-- **this is the correct, demojibaked text!**

有人能解释一下吗?我不明白当直接在
u''
字符串上操作时,如何使其不解码到7位
ascii
范围

首先,以您知道的编码方式对其进行编码

>>> tag = u'\xc1\xf3\xf0\xe6\xf3\xe9\xf1\xea\xe8\xe5 \xef\xeb\xff\xf1\xea\xe8'
>>> raw = tag.encode('latin-1'); raw
'\xc1\xf3\xf0\xe6\xf3\xe9\xf1\xea\xe8\xe5 \xef\xeb\xff\xf1\xea\xe8'
然后你可以用正确的编码对它进行解码

>>> fixed = raw.decode('cp1251'); print fixed
Буржуйские пляски

嘿!有趣!非常感谢你!我想我并没有想到这和我当时所做的事情是一样的,因为我真的不理解你提供的这个编码步骤。我从诱变剂那里得到了一个Unicode字符串(为什么诱变剂在标记指定为8位时输出Unicode?我不知道)。我把这个Unicode编码成一个拉丁-1字符串。由于所有字节都在8位范围内,当我尝试对字符串进行
decode('cp1251)
解码时,字符串之间的实际区别是什么?为什么Unicode解码失败?失败的原因是解码(enc)与编码(sys.getdefaultencoding())。解码(enc),而
sys.getdefaultencoding()
几乎总是
='ascii'
。感谢您提供的澄清。为了澄清我关于编码(“拉丁-1”)步骤的另一个困惑点,我不确定我为什么要先编码为拉丁-1。有人用了
cp1251
,而ID3规范认为它是拉丁语-1,所以我得到了mojibake。我要做的是将
cp1251
转换成Unicode。如果我使用的是笔和键盘,我会在
cp1251
中查找这些错误的Unicode编码的代码点,然后得到真正的Unicode代码点。也许您可以解释一下为什么
u'。解码(enc)
首先必须涉及中间
encode(enc)
?因为您无法解码
unicode
对象。它已经被解码成Unicode代码点。Unicode对象只能编码为ByTestRing,而ByTestRing只能解码为Unicode对象。那么,为什么Python不能将mojibake字符串编码为CP1251呢?很简单,它是一个Unicode对象,在Unicode中\xc1是Á。但是,CP1251没有Á。非常感谢frb和其他所有人。这个问答和帖子真的帮助了我。我现在对这一点的理解让我感到很舒服。据我所知,在我的ID3v2标签中有
cp1251
-由testrings编码。标签错误地指出bytestring是
拉丁语-1
。因此,诱变剂获取这些ByTestRing,并对其进行解码('latin-1'),向我返回一个
unicode
对象。这个unicode对象是mojibake。为了获得原始的bytestring,我获取
unicode
对象并将其重新编码为拉丁语-1:
{unicode}.encode('Latin-1')
。然后我可以执行所需的
{str}.decode()
>>> fixed = raw.decode('cp1251'); print fixed
Буржуйские пляски