Конвертер кодировок текста

UnicodeDecodeError в Python: как прочитать файл с русским текстом

Исправить текст в конвертере ↓

Python 3 хранит текст в Юникоде, а файл на диске — это байты. При чтении файла в текстовом режиме Python переводит байты в текст по указанной кодировке. Если кодировку не указать, используется кодировка по умолчанию: в Linux и macOS это UTF-8, а в Windows до версии Python 3.15 — системная кодировка, на русской Windows обычно Windows-1251. Когда байты файла не подходят к кодировке, чтение прерывается ошибкой UnicodeDecodeError.

Что означает текст ошибки

ОшибкаЧто произошлоРешение
'utf-8' codec can't decode byte 0xcf in position 0: invalid continuation byteФайл в Windows-1251 (байты от 0xC0 до 0xFF — русские буквы), а читается как UTF-8encoding='cp1251'
'charmap' codec can't decode byte 0x98 in position 12: character maps to <undefined>Файл в UTF-8, а Python на Windows читает его как Windows-1251: байта 0x98 в ней нет, а в UTF-8 он входит, например, в букву «И»encoding='utf-8'
Ошибки нет, но вместо текста ПриветФайл в UTF-8 прочитан как Windows-1251encoding='utf-8'
Строка начинается с  или первый столбец CSV называется 'id'Файл в UTF-8 с меткой BOM — так сохраняют Excel и Блокнотencoding='utf-8-sig'

Число после byte подсказывает кодировку. Байты 0xD0 и 0xD1 перед каждой русской буквой — признак UTF-8, одиночные байты от 0xC0 до 0xFF — признак Windows-1251, байты от 0x80 до 0xAF и от 0xE0 до 0xEF — признак DOS-кодировки CP866.

Как указать кодировку

  • Обычный файл: open('data.txt', encoding='cp1251'). Всегда указывайте encoding явно — тогда программа будет работать одинаково на любом компьютере.
  • pandas: pd.read_csv('data.csv', encoding='cp1251'); для файлов из Excel с меткой BOM — encoding='utf-8-sig'. Чтобы Excel правильно открыл сохраненный CSV, записывайте его так: df.to_csv('out.csv', encoding='utf-8-sig').
  • Байты из сети или базы: data.decode('cp1251'). В библиотеке requests, если r.text выдает кракозябры, укажите кодировку перед чтением: r.encoding = 'utf-8'.
  • Вывод программы через subprocess на Windows: консольные программы часто выводят текст в CP866, поэтому подойдет subprocess.run(cmd, capture_output=True, encoding='cp866').

Параметр errors='replace' позволяет дочитать файл, заменив непонятные байты на «�». Используйте его только для диагностики: испорченные символы потом уже не восстановить.

Как узнать кодировку файла

Самый простой способ — загрузить файл в конвертер ниже: он покажет кодировку и исправленный текст. В коде кодировку можно угадать библиотекой charset-normalizer (ее же использует requests):

from charset_normalizer import from_path; print(from_path('data.txt').best().encoding)

Определение кодировки всегда остается угадыванием, особенно на коротких файлах. Если файлы приходят из одного источника, лучше один раз выяснить их кодировку и указывать ее явно.

Частые вопросы

Почему программа работает на Linux и Mac, а на Windows падает с UnicodeDecodeError?
Без параметра encoding Python использует кодировку системы: UTF-8 в Linux и macOS и Windows-1251 на русской Windows (до Python 3.15). Укажите encoding='utf-8' в open() или запускайте Python в режиме UTF-8 командой python -X utf8. Начиная с Python 3.15 этот режим включен по умолчанию.
Что делать с ошибкой UnicodeEncodeError при выводе русского текста через print?
Это обратная ситуация: консоль не может показать символы. Обычно это старая версия Python в командной строке Windows. Помогает запуск с python -X utf8, переменная окружения PYTHONIOENCODING=utf-8 или Windows Terminal вместо старой консоли. Подробнее — в инструкции о командной строке Windows.
Чем cp1251 отличается от windows-1251 в Python?
Ничем: это два названия одной кодировки. Так же cp866 и ibm866 — одна и та же DOS-кодировка, а utf-8 и utf8 — UTF-8.