Python bot de IRC y emisión de codificación
Pregunta
Actualmente tengo un simple bot de IRC escrito en Python.
Desde que emigró a Python 3.0 que diferencia entre bytes y cadenas Unicode empecé a tener problemas de codificación. En concreto, con los demás no enviar UTF-8.
Ahora, tan sólo pudiera decir todo el mundo para enviar UTF-8 (que deberían independientemente), pero una solución aún mejor sería tratar de conseguir pitón por defecto a alguna otra codificación o tales.
Hasta ahora, el código es el siguiente:
data = str(irc.recv(4096),"UTF-8", "replace")
Lo que al menos no lanza excepciones. Sin embargo, quiero ir más allá de ella:. Quiero que mi bot por defecto a otro sistema de codificación, o tratar de detectar "caracteres problemáticos" de alguna manera
Además, tengo que averiguar lo que esta misteriosa codificación que utiliza mIRC realidad es - como otros clientes parecen funcionar bien y enviar UTF-8 como deberían
.¿Cómo debo ir haciendo esas cosas?
Solución 4
Ok, después de algunas investigaciones resulta Chardet está teniendo problemas con Python 3. La solución resulta que es más sencillo de lo que pensaba. Elegí a caer de nuevo si CP1252 UTF-8 no es suficiente:
data = irc.recv ( 4096 )
try: data = str(data,"UTF-8")
except UnicodeDecodeError: data = str(data,"CP1252")
Lo que parece estar funcionando. A pesar de que no detecta la codificación, y por lo que si alguien entró con una codificación que no es ni UTF-8 ni CP1252 vez más voy a tener un problema.
Esto es realmente sólo una solución temporal.
Otros consejos
Chardet debería ayudar -. Que es la biblioteca de Python canónica para la detección de códigos desconocidos
El Chardet será probablemente la mejor solución como se ha mencionado RichieHindle. Sin embargo, si se quiere cubrir alrededor del 90% del texto que verá usted puede usar lo que yo uso:
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
Usando sólo Chardet conduce a resultados pobres para situaciones donde los mensajes son cortos (que es el caso en el IRC).
Chardet combina con la codificación para recordar usuario específico a través de los mensajes podría tener sentido. Sin embargo, para simplificar, que haría uso de algunas codificaciones presumibles (codificaciones dependen de la cultura y la época, consulte http: / /en.wikipedia.org/wiki/Internet_Relay_Chat#Character_encoding ) y si no, me gustaría ir a Chardet (si alguien usa algunas de las codificaciones del este de Asia, esto nos ayudará a cabo).
Por ejemplo:
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