Вопрос-Ответ

How to determine the encoding of text

Как определить кодировку текста

Я получил некоторый текст в кодировке, но я не знаю, какая кодировка использовалась. Есть ли способ определить кодировку текстового файла с помощью Python? Как я могу определить кодировку / кодовую страницу текстового файла, относящегося к C #.

Переведено автоматически
Ответ 1

РЕДАКТИРОВАТЬ: chardet кажется необязательным, но большая часть ответа применима. Проверьте https://pypi.org/project/charset-normalizer / для альтернативы

Все время корректно определять кодировку невозможно.

(Из часто задаваемых вопросов chardet:)


Однако некоторые кодировки оптимизированы для определенных языков, и языки не случайны. Некоторые последовательности символов появляются постоянно, в то время как другие последовательности не имеют смысла. Человек, свободно владеющий английским языком, который открывает газету и находит “txzqJv 2!dasd0a QqdKjvz”, мгновенно поймет, что это не английский (даже если он полностью состоит из английских букв). Изучая большое количество “типичного” текста, компьютерный алгоритм может имитировать беглость такого рода и сделать обоснованное предположение о языке текста.


Существует библиотека chardet, которая использует это исследование для попытки определить кодировку. chardet - это порт кода автоматического обнаружения в Mozilla.

Вы также можете использовать UnicodeDammit. Он попробует следующие методы:


  • Кодировка, обнаруженная в самом документе: например, в объявлении XML или (для документов HTML) в метатеге http-equiv. Если Beautiful Soup обнаруживает этот тип кодировки в документе, он снова анализирует документ с самого начала и пробует новую кодировку. Единственное исключение - это если вы явно указали кодировку, и эта кодировка действительно сработала: тогда он проигнорирует любую кодировку, которую найдет в документе.

  • Кодировка определяется путем просмотра первых нескольких байтов файла. Если кодировка обнаружена на этом этапе, это будет одна из кодировок UTF-*, EBCDIC или ASCII.

  • Кодировка, которую отслеживает библиотека chardet, если она у вас установлена.

  • UTF-8

  • Windows-1252

Ответ 2

Другой вариант для определения кодировки - использовать libmagic (который является кодом, стоящим за командой file). Доступно множество привязок python.

Привязки python, которые находятся в дереве исходных текстов файлов, доступны как python-magic (или python3-magic) пакет debian. Он может определить кодировку файла, выполнив:

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

В pypi есть пакет pip с идентичным именем, но несовместимый с python-magic, который также использует libmagic. Он также может получить кодировку, выполнив:

import magic

blob = open('unknown-file', 'rb').read()
m = magic.Magic(mime_encoding=True)
encoding = m.from_buffer(blob)
Ответ 3

Some encoding strategies, please uncomment to taste :

#!/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

You might like to check the encoding by opening and reading the file in a form of a loop... but you might need to check the filesize first :

# 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
Ответ 4

Here is an example of reading and taking at face value a chardet encoding prediction, reading n_lines from the file in the event it is large.

chardet also gives you a probability (i.e. confidence) of it's encoding prediction (haven't looked how they come up with that), which is returned with its prediction from chardet.predict(), so you could work that in somehow if you like.

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']
python