Cómo determinar la codificación del texto.

Resuelto Nope asked hace 15 años • 17 respuestas

Recibí un texto codificado, pero no sé qué juego de caracteres se utilizó. ¿Existe alguna manera de determinar la codificación de un archivo de texto usando Python? ¿Cómo puedo detectar la codificación/página de códigos de un archivo de texto con C#?

Nope avatar Jan 13 '09 00:01 Nope
Aceptado

EDITAR: chardet parece no estar mantenido pero la mayor parte de la respuesta se aplica. Consulte https://pypi.org/project/charset-normalizer/ para obtener una alternativa

Detectar correctamente la codificación en todo momento es imposible .

(De las preguntas frecuentes de Chardet :)

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 que habla inglés con fluidez y abre un periódico y encuentra “txzqJv 2!dasd0a QqdKjvz” reconocerá instantáneamente que eso no es inglés (aunque esté compuesto enteramente de letras inglesas). Al estudiar muchos textos “típicos”, un algoritmo informático puede simular este tipo de fluidez y hacer una conjetura fundamentada sobre el lenguaje de un texto.

Existe la biblioteca chardet que utiliza ese estudio para intentar detectar la codificación. chardet es una adaptación del código de detección automática de Mozilla.

También puedes usar UnicodeMaldita sea . Probará 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 equivalente a http. 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 chardet , si la tienes instalada.
  • UTF-8
  • Windows-1252
nosklo avatar Jan 12 '2009 17:01 nosklo

Otra opción para resolver la codificación es usar libmagic (que es el código detrás del comando file ). Hay una gran cantidad de enlaces de Python disponibles.

Los enlaces de Python que se encuentran en el árbol de fuentes de archivos están disponibles como el paquete Debian python-magic (o python3-magic ). Puede determinar la codificación de un archivo haciendo:

import magic

blob = open('unknown-file', 'rb').read()
m = magic.open(magic.MAGIC_MIME_ENCODING)
m.load()
encoding = m.buffer(blob)  # "utf-8" "us-ascii" etc

Hay un paquete python-magic pip con el mismo nombre, pero incompatible, en pypi que también usa libmagic. También puede obtener la codificación haciendo:

import magic

blob = open('unknown-file', 'rb').read()
m = magic.Magic(mime_encoding=True)
encoding = m.from_buffer(blob)
Hamish Downer avatar Apr 24 '2013 23:04 Hamish Downer

Algunas estrategias de codificación, descomente al gusto:

#!/bin/bash
#
tmpfile=$1
echo '-- info about file file ........'
file -i $tmpfile
enca -g $tmpfile
echo 'recoding ........'
#iconv -f iso-8859-2 -t utf-8 back_test.xml > $tmpfile
#enca -x utf-8 $tmpfile
#enca -g $tmpfile
recode CP1250..UTF-8 $tmpfile

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:

# PYTHON
encodings = ['utf-8', 'windows-1250', 'windows-1252'] # add more
for e in encodings:
    try:
        fh = codecs.open('file.txt', 'r', encoding=e)
        fh.readlines()
        fh.seek(0)
    except UnicodeDecodeError:
        print('got unicode error with %s , trying different encoding' % e)
    else:
        print('opening the file with encoding:  %s ' % e)
        break
zzart avatar Feb 06 '2013 16:02 zzart

A continuación se muestra un ejemplo de cómo leer y tomar al pie de la letra una chardetpredicción de codificación, leyendo n_linesdel archivo en caso de que sea grande.

chardettambién le brinda una probabilidad (es decir confidence) de su predicción de codificación (no he visto cómo se les ocurrió eso), que se devuelve con su predicción de chardet.predict(), por lo que podría trabajar eso de alguna manera si lo desea.

import chardet
from pathlib import Path

def predict_encoding(file_path: Path, n_lines: int=20) -> str:
    '''Predict a file's encoding using chardet'''

    # Open the file as binary data
    with Path(file_path).open('rb') as f:
        # Join binary lines for specified number of lines
        rawdata = b''.join([f.readline() for _ in range(n_lines)])

    return chardet.detect(rawdata)['encoding']
ryanjdillon avatar Jul 18 '2017 13:07 ryanjdillon

Esto podría ser útil

from bs4 import UnicodeDammit
with open('automate_data/billboard.csv', 'rb') as file:
   content = file.read()

suggestion = UnicodeDammit(content)
suggestion.original_encoding
#'iso-8859-1'
richinex avatar Mar 25 '2020 23:03 richinex