Detectar correctamente la codificación en todo momento es imposible .
(De chardet FAQ :)
Sin embargo, algunas codificaciones están optimizadas para idiomas específicos, y los idiomas no son aleatorios. Algunas secuencias de personajes aparecen todo el tiempo, mientras que otras secuencias no tienen sentido. Una persona con fluidez en inglés que abre un periódico y encuentra "txzqJv 2! Dasd0a QqdKjvz" reconocerá instantáneamente que eso no es inglés (aunque esté compuesto completamente de letras en inglés). Al estudiar muchos textos "típicos", un algoritmo informático puede simular este tipo de fluidez y hacer una suposición educada sobre el lenguaje de un texto.
Existe la biblioteca de chardet que utiliza ese estudio para intentar detectar la codificación. chardet es un puerto del código de autodetección en Mozilla.
También puede usar UnicodeDammit . Intentará los siguientes métodos:
- Una codificación descubierta en el propio documento: por ejemplo, en una declaración XML o (para documentos HTML) una etiqueta META http-equiv. Si Beautiful Soup encuentra este tipo de codificación dentro del documento, analiza el documento nuevamente desde el principio y prueba la nueva codificación. La única excepción es si especificó explícitamente una codificación, y esa codificación realmente funcionó: entonces ignorará cualquier codificación que encuentre en el documento.
- Una codificación detectada al observar los primeros bytes del archivo. Si se detecta una codificación en esta etapa, será una de las codificaciones UTF- *, EBCDIC o ASCII.
- Una codificación detectada por la biblioteca de chardet , si la tiene instalada.
- UTF-8
- Windows-1252
chardet
referencia Parece bueno, aunque un poco lento.Otra opción para resolver la codificación es usar libmagic (que es el código detrás del comando de archivo ). Hay una gran cantidad de enlaces de python disponibles.
Los enlaces de python que viven en el árbol de origen de archivos están disponibles como el paquete debian python-magic (o python3-magic ). Puede determinar la codificación de un archivo haciendo:
Hay un paquete pip -python-magic idénticamente nombrado, pero incompatible, en pypi que también usa
libmagic
. También puede obtener la codificación, haciendo:fuente
libmagic
es de hecho una alternativa viable parachardet
. ¡Y gran información sobre los distintos paquetes nombradospython-magic
! Estoy seguro de que esta ambigüedad muerde a muchas personasfile
no es particularmente bueno para identificar el lenguaje humano en archivos de texto. Es excelente para identificar varios formatos de contenedor, aunque a veces tiene que saber lo que significa ("documento de Microsoft Office" podría significar un mensaje de Outlook, etc.).open()
:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 169799: invalid start byte
. La codificación del archivo de acuerdo con vim:set fileencoding
eslatin1
.errors='ignore'
, la salida del código de ejemplo es menos útilbinary
.Algunas estrategias de codificación, por favor descomente al gusto:
Es posible que desee verificar la codificación abriendo y leyendo el archivo en forma de bucle ... pero es posible que primero deba verificar el tamaño del archivo:
fuente
io
, comoio.open(filepath, 'r', encoding='utf-8')
, que es más conveniente, porquecodecs
no se convierte\n
automáticamente en lectura y escritura. Más sobre AQUÍAquí hay un ejemplo de leer y tomar al pie de la letra una
chardet
predicción de codificación, leern_lines
del archivo en caso de que sea grande.chardet
también le da una probabilidad (es decirconfidence
) de que está prediciendo la codificación (no he visto cómo se les ocurre), que se devuelve con su predicciónchardet.predict()
, por lo que podría trabajar de alguna manera si lo desea.fuente
def predict_encoding(file_path, n=20): ... skip ... and then rawdata = b''.join([f.read() for _ in range(n)])
he probado esta función en Python 3.6, funcionó perfectamente con codificaciones "ascii", "cp1252", "utf-8", "unicode". Así que esto definitivamente es un voto positivo.fuente
Dependiendo de su plataforma, simplemente opto por usar el
file
comando de shell de Linux . Esto funciona para mí ya que lo estoy usando en un script que se ejecuta exclusivamente en una de nuestras máquinas Linux.Obviamente, esta no es una solución o respuesta ideal, pero podría modificarse para satisfacer sus necesidades. En mi caso, solo necesito determinar si un archivo es UTF-8 o no.
fuente
Esto puede ser útil.
fuente
En principio, es imposible determinar la codificación de un archivo de texto, en el caso general. Entonces, no, no hay una biblioteca estándar de Python para hacer eso por usted.
Si tiene un conocimiento más específico sobre el archivo de texto (por ejemplo, que es XML), puede haber funciones de biblioteca.
fuente
Si conoce el contenido del archivo, puede intentar decodificarlo con varias codificaciones y ver cuál falta. En general no hay forma ya que un archivo de texto es un archivo de texto y esos son estúpidos;)
fuente
Este sitio tiene un código python para reconocer ascii, codificar con boms y utf8 no bom: https://unicodebook.readthedocs.io/guess_encoding.html . Lea el archivo en la matriz de bytes (datos): http://www.codecodex.com/wiki/Read_a_file_into_a_byte_array . Aquí hay un ejemplo. Estoy en osx
fuente