Все время корректно определять кодировку невозможно.
(Из часто задаваемых вопросов 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. Он может определить кодировку файла, выполнив:
В 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 :
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
defpredict_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 _ inrange(n_lines)])