目前我有一个用python编写的简单IRC机器人。
因为我将它迁移到python 3.0,它区分了字节和unicode字符串,所以我开始遇到编码问题。特别是,其他人不发送UTF-8。
现在,我可以告诉大家发送UTF-8(他们不应该这样做),但更好的解决方案是尝试将python默认为其他编码等。
到目前为止代码看起来像这样:
data = str(irc.recv(4096),"UTF-8", "replace")
至少不会抛出异常。但是,我想要通过它:我希望我的机器人默认使用其他编码,或者尝试以某种方式检测“麻烦的角色”。
此外,我需要弄清楚mIRC实际使用的这种神秘编码是什么 - 因为其他客户端似乎工作正常并且发送UTF-8就像它们应该的那样。
我应该怎么做呢?
答案 0 :(得分:3)
chardet应该有所帮助 - 它是用于检测未知编码的规范Python库。
答案 1 :(得分:0)
RichieHindle提到,chardet可能是你最好的解决方案。但是,如果您想要覆盖大约90%的文本,您将看到您可以使用我使用的内容:
def decode(bytes):
try:
text = bytes.decode('utf-8')
except UnicodeDecodeError:
try:
text = bytes.decode('iso-8859-1')
except UnicodeDecodeError:
text = bytes.decode('cp1252')
return text
def encode(bytes):
try:
text = bytes.encode('utf-8')
except UnicodeEncodeError:
try:
text = bytes.encode('iso-8859-1')
except UnicodeEncodeError:
text = bytes.encode('cp1252')
return text
答案 2 :(得分:0)
仅使用chardet会导致消息短缺的情况(IRC中就是这种情况)。
Chardet结合在整个消息中记住特定用户的编码可能有意义。然而,为简单起见,我会使用一些可能的编码(编码取决于文化和时代,见http://en.wikipedia.org/wiki/Internet_Relay_Chat#Character_encoding),如果它们失败,我会去chardet(如果有人使用一些东亚编码,这将有助于我们出去了。)
例如:
def decode_irc(raw, preferred_encs = ["UTF-8", "CP1252", "ISO-8859-1"]):
changed = False
for enc in preferred_encs:
try:
res = raw.decode(enc)
changed = True
break
except:
pass
if not changed:
try:
enc = chardet.detect(raw)['encoding']
res = raw.decode(enc)
except:
res = raw.decode(enc, 'ignore')
return res
答案 3 :(得分:-1)
好的,经过一些调查后,chardet遇到了python 3的麻烦。事实证明,解决方案比我想象的要简单。如果UTF-8没有削减它,我选择退回CP1252:
data = irc.recv ( 4096 )
try: data = str(data,"UTF-8")
except UnicodeDecodeError: data = str(data,"CP1252")
这似乎有效。虽然它没有检测到编码,所以如果有人进来的编码既不是UTF-8也不是CP1252我会再次遇到问题。
这实际上只是一个临时解决方案。