2009-06-02 6 views
3

현재 파이썬으로 작성된 간단한 IRC 봇이 있습니다.파이썬 IRC 봇 및 인코딩 문제

바이트와 유니 코드 문자열을 구별하는 python 3.0으로 마이그레이션 한 이래로 인코딩 문제가 발생하기 시작했습니다. 특히, 다른 사람들이 UTF-8을 보내지 않는 경우.

이제 모든 사람들에게 UTF-8을 보내라고 말할 수 있습니다.하지만 더 나은 솔루션은 파이썬을 다른 인코딩이나 기본값으로 설정하려고하는 것입니다.

는 지금까지 코드는 다음과 같습니다

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

적어도 예외가 발생하지 않는. 그러나 나는 그것을 지나치기를 원한다. 나는 로봇이 다른 인코딩을 기본으로하고 싶어하거나, "귀찮은 등장 인물"을 어떻게 든 감지하려고 노력한다.

또한 mIRC가 실제로 사용하는이 신비한 인코딩이 무엇인지 파악해야합니다. 다른 클라이언트가 제대로 작동하고 UTF-8을 보내야하는 것처럼 보입니다.

어떻게해야합니까?

답변

-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가 아닌 인코딩을 사용하게되면 다시 문제가 발생합니다.

이것은 실제로는 일시적인 해결책입니다.

+1

0을 제외한 모든 바이트 값에 코드 포인트를 할당하므로 cp1252는 0이 아닌 바이트 시퀀스에 대해 항상 작동하는 것처럼 보입니다. – RichieHindle

3

chardet 도움이 될만한 것은 알려지지 않은 인코딩을 탐지하기위한 표준 파이썬 라이브러리입니다.

+0

지금 그것을 시도. 나는 그것이 나를 필요로하는 곳을 보게 될 것이다. – cwj

0

Chardet은 아마도 RichieHindle이 언급 한대로 최상의 솔루션이 될 것입니다. 단지 chardet를 사용

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

는 메시지가 경우에 인 (짧은 상황 가난한 결과에 이르게 : 당신이 텍스트의 약 90 %를 커버하려는 경우, 당신은 당신이 내가 사용하는 것을 사용할 수 있습니다 볼 수 있습니다 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 
+0

이것은'res = raw.decode ('U')'를 시도한 다음 즉시 기권합니다. –