Сообщить об ошибке.

Модуль chardet в Python, определение кодировки

Распознавание кодировки символов Python

Когда мы думаем о тексте, то представляем слова и буквы, которые видим на экране компьютера. Но компьютеры не работают с буквами и символами. Они имеют дело с битами и байтами. Каждый фрагмент текста, который выводится на экране, на самом деле хранится в определенной кодировке символов. Существует множество различных кодировок, некоторые из которых оптимизированы для определенных языков, таких как русский, китайский или английский, а другие могут использоваться для нескольких языков. Грубо говоря, кодировка символов обеспечивает соответствие между тем, что мы видим на экране, и тем, что компьютер фактически хранит в памяти и на диске.

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

Модуль chardet отлично поддерживает и определяет русские кодировки: KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251(Cyrillic)

Установка модуля chardet в виртуальное окружение.

# создаем виртуальное окружение, если нет
$ python3 -m venv .venv --prompt VirtualEnv
# активируем виртуальное окружение 
$ source .venv/bin/activate
# ставим модуль chardet
(VirtualEnv):~$ python -m pip install -U chardet

Примеры автоматического определения кодировки символов:

Самый простой способ автоматически определить кодировку - это использовать функцию обнаружения detect() модуля chardet.

>>> import urllib.request, chardet
>>> rawdata = urllib.request.urlopen('http://yandex.ru/').read()
>>> chardet.detect(rawdata)
# {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}
>>> rawdata = urllib.request.urlopen('https://www.zeit.de/index').read()
>>> chardet.detect(rawdata)
# {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

Расширенное использование модуля chardet.

Если имеется большой объем текста/данных, то можно вызывать обнаружение кодировки постепенно. Как только модуль будет достаточно уверен в своих результатах, он остановится.

Для такого поведения необходимо создать объект UniversalDetector(), затем повторно вызывать его метод подачи .feed() с каждым блоком текста. Если созданный детектор достигнет минимального порога достоверности, он установит для Detector.done значение True.

В конце работы детектора необходимо вызвать Detector.close(), который выполнит некоторые окончательные вычисления в случае, если детектор не достиг минимального порога достоверности.

import urllib.request
from chardet.universaldetector import UniversalDetector

usock = urllib.request.urlopen('https://www.zeit.de/index')
# создаем детектор
detector = UniversalDetector()
for line in usock.readlines():
    # скармливаем детектору строки
    detector.feed(line)
    if detector.done: 
        # если детектор определил 
        # кодировку, то прерываем цикл
        break
# закрываем детектор
detector.close()
# закрываем соединение с сайтом
usock.close()
print(detector.result)
# {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

Пример определения кодировки нескольких файлов.

Для определения кодировки текстовых файлов, их необходимо открывать в режиме чтения байтов: more='rb'

import glob
from chardet.universaldetector import UniversalDetector

# создаем детектор
detector = UniversalDetector()
for filename in glob.glob('*.xml'):
    print(filename.ljust(60), end='')
    # сбрасываем детектор 
    # в исходное состояние
    detector.reset()
    # проходимся по строкам очередного
    # файла в режиме 'rb'
    for line in open(filename, 'rb'):
        detector.feed(line)
        if detector.done: break
    detector.close()
    print(detector.result)