He tenido que enfrentar este problema demasiadas veces. El problema que tuve contenía cadenas en diferentes esquemas de codificación. Así que escribí un método para decodificar una cadena de forma heurística en función de ciertas características de diferentes codificaciones.
def decode_heuristically(string, enc = None, denc = sys.getdefaultencoding()):
"""
Try to interpret 'string' using several possible encodings.
@input : string, encode type.
@output: a list [decoded_string, flag_decoded, encoding]
"""
if isinstance(string, unicode): return string, 0, "utf-8"
try:
new_string = unicode(string, "ascii")
return string, 0, "ascii"
except UnicodeError:
encodings = ["utf-8","iso-8859-1","cp1252","iso-8859-15"]
if denc != "ascii": encodings.insert(0, denc)
if enc: encodings.insert(0, enc)
for enc in encodings:
if (enc in ("iso-8859-15", "iso-8859-1") and
re.search(r"[\x80-\x9f]", string) is not None):
continue
if (enc in ("iso-8859-1", "cp1252") and
re.search(r"[\xa4\xa6\xa8\xb4\xb8\xbc-\xbe]", string)\
is not None):
continue
try:
new_string = unicode(string, enc)
except UnicodeError:
pass
else:
if new_string.encode(enc) == string:
return new_string, 0, enc
# If unable to decode,doing force decoding i.e.neglecting those chars.
output = [(unicode(string, enc, "ignore"), enc) for enc in encodings]
output = [(len(new_string[0]), new_string) for new_string in output]
output.sort()
new_string, enc = output[-1][1]
return new_string, 1, enc
Para añadir a esto este enlace da una buena retroalimentación sobre qué codificación etc - Why we need sys.setdefaultencoging in py script
se va a ayudarme en todas las situaciones? ¿Hay alguna solución generalizada? – user12345
Podemos eliminar esos caracteres como '\ x' en mi ejemplo, de la cadena original. – user12345
@alis: Puede usar chardet (http://chardet.feedparser.org/) para adivinar la codificación. – johnbaum