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?

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top