2009-06-02 3 views
3

В настоящее время у меня есть простой IRC-бот, написанный на питоне.Python IRC bot и проблема с кодировкой

Поскольку я перенес его в python 3.0, который различает байты и строки Unicode, у меня возникли проблемы с кодировкой. В частности, если другие не отправляют UTF-8.

Теперь я могу просто сказать всем, что нужно отправить UTF-8 (что они должны делать независимо), но даже лучшее решение будет пытаться заставить python по умолчанию использовать какую-либо другую кодировку или такую.

Пока код выглядит следующим образом:

data = str(irc.recv(4096),"UTF-8", "replace") 

Который по крайней мере, не бросать исключения. Тем не менее, я хочу пройти мимо него: я хочу, чтобы мой бот по умолчанию использовал другую кодировку или каким-то образом обнаружил «неприятные символы».

Кроме того, мне нужно выяснить, что такое таинственная кодировка, которую использует mIRC на самом деле, - поскольку другие клиенты работают нормально и отправляют UTF-8, как они должны.

Как я должен делать это?

ответ

-1

Хорошо, после некоторых исследований выясняется, что у гарнизона возникают проблемы с python 3. Решение, как оказалось, проще, чем я думал. Я решил отступить на CP1252, если UTF-8 не разрезает его:

data = irc.recv (4096) 
try: data = str(data,"UTF-8") 
except UnicodeDecodeError: data = str(data,"CP1252") 

Который, кажется, работает. Хотя он не обнаруживает кодировку, и поэтому, если кто-то пришел с кодировкой, которая не является ни UTF-8, ни CP1252, у меня снова возникнет проблема.

Это действительно временное решение.

+1

cp1252 всегда будет работать для любой ненулевой последовательности байтов, поскольку он присваивает кодовую точку каждому байтовому значению, кроме нуля. – RichieHindle

3

chardet должен помочь - это каноническая библиотека Python для обнаружения неизвестных кодировок.

+0

Пытаться что сейчас. Я посмотрю, где это меня принимает. – cwj

0

Шедевр, вероятно, будет вашим лучшим решением, как упоминалось в RichieHindle. Тем не менее, если вы хотите, чтобы покрыть около 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 
0

Использование только chardet приводит к плохим результатам для ситуаций, когда сообщения коротки (что имеет место в IRC).

Chardet в сочетании с запоминанием кодировки для конкретного пользователя в сообщениях может иметь смысл. Тем не менее, для простоты я бы использовал некоторые предположительные кодировки (кодировки зависят от культуры и эпохи, см. http://en.wikipedia.org/wiki/Internet_Relay_Chat#Character_encoding), и если они потерпят неудачу, я поеду в чарт (если кто-то использует некоторые восточноазиатские кодировки, это поможет нам).

Например:

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 
+0

Это попытка выполнить 'res = raw.decode ('U')', а затем быстро отказаться. –

 Смежные вопросы

  • Нет связанных вопросов^_^