Кодировка windows 1251 в python

I’m trying to convert file content from Windows-1251 (Cyrillic) to Unicode with Python. I found this function, but it doesn’t work.

#!/usr/bin/env python

import os
import sys
import shutil

def convert_to_utf8(filename):
# gather the encodings you think that the file may be
# encoded inside a tuple
encodings = ('windows-1253', 'iso-8859-7', 'macgreek')

# try to open the file and exit if some IOError occurs
try:
    f = open(filename, 'r').read()
except Exception:
    sys.exit(1)

# now start iterating in our encodings tuple and try to
# decode the file
for enc in encodings:
    try:
        # try to decode the file with the first encoding
        # from the tuple.
        # if it succeeds then it will reach break, so we
        # will be out of the loop (something we want on
        # success).
        # the data variable will hold our decoded text
        data = f.decode(enc)
        break
    except Exception:
        # if the first encoding fail, then with the continue
        # keyword will start again with the second encoding
        # from the tuple an so on.... until it succeeds.
        # if for some reason it reaches the last encoding of
        # our tuple without success, then exit the program.
        if enc == encodings[-1]:
            sys.exit(1)
        continue

# now get the absolute path of our filename and append .bak
# to the end of it (for our backup file)
fpath = os.path.abspath(filename)
newfilename = fpath + '.bak'
# and make our backup file with shutil
shutil.copy(filename, newfilename)

# and at last convert it to utf-8
f = open(filename, 'w')
try:
    f.write(data.encode('utf-8'))
except Exception, e:
    print e
finally:
    f.close()

How can I do that?

Thank you

Chilledrat's user avatar

Chilledrat

2,6033 gold badges29 silver badges38 bronze badges

asked Apr 27, 2011 at 15:55

Alex's user avatar

2

import codecs

f = codecs.open(filename, 'r', 'cp1251')
u = f.read()   # now the contents have been transformed to a Unicode string
out = codecs.open(output, 'w', 'utf-8')
out.write(u)   # and now the contents have been output as UTF-8

Is this what you intend to do?

answered Apr 27, 2011 at 16:15

buruzaemon's user avatar

buruzaemonburuzaemon

3,8471 gold badge23 silver badges44 bronze badges

3

This is just a guess, since you didn’t specify what you mean by «doesn’t work».

If the file is being generated properly but appears to contain garbage characters, likely the application you’re viewing it with does not recognize that it contains UTF-8. You need to add a BOM to the beginning of the file — the 3 bytes 0xEF,0xBB,0xBF (unencoded).

answered Apr 27, 2011 at 16:07

Mark Ransom's user avatar

Mark RansomMark Ransom

301k42 gold badges400 silver badges625 bronze badges

0

If you use the codecs module to open the file, it will do the conversion to Unicode for you when you read from the file. E.g.:

import codecs
f = codecs.open('input.txt', encoding='cp1251')
assert isinstance(f.read(), unicode)

This only makes sense if you’re working with the file’s data in Python. If you’re trying to convert a file from one encoding to another on the filesystem (which is what the script you posted tries to do), you’ll have to specify an actual encoding, since you can’t write a file in «Unicode».

answered Apr 27, 2011 at 16:02

Will McCutchen's user avatar

Will McCutchenWill McCutchen

13.1k3 gold badges44 silver badges43 bronze badges

7

Python поддерживает работу с кодировками, в том числе и с Windows-1251, необходимой для работы с текстовой информацией на русском языке. При работе с данной кодировкой в Python, необходимо учитывать определенные особенности.

Для чтения файла в кодировке Windows-1251 можно использовать следующий код:

with open('file.txt', encoding='cp1251') as f:
text = f.read()

Аналогично, текст можно записать в файл с указанием нужной кодировки:

with open('file.txt', 'w', encoding='cp1251') as f:
f.write(text)

Если необходимо работать с строками в кодировке Windows-1251, можно воспользоваться модулем codecs:

import codecs

text = 'текст для работы в Windows-1251'
encoded_text = codecs.encode(text, 'cp1251')
decoded_text = codecs.decode(encoded_text, 'cp1251')

Если при выводе или обработке текста встречаются ошибки, связанные с кодировкой, можно воспользоваться методом encode с параметром ‘ignore’, который будет игнорировать ошибки:

text = 'текст с ошибкой кодировки'
encoded_text = text.encode('cp1251', 'ignore')

Python 3, you mostly don’t have to care about the encoding of text strings, if you work with UTF-8.

Python с нуля. Кодировка UTF 8 в Python

ПРОБЛЕМЫ С КОДИРОВКОЙ. Utf8 в Windows? Кодировка utf8 sublime text

Что такое Кодировка? (Character Encoding, Кодировка Символов, UTF-8, Windows-1251) #Shorts

How to Run Python Programs ( .py files ) on Windows 11 ( All Options )

НАСТРОЙКА PyCharm И УСТАНОВКА Python 3.11 — ЛЕГКО И БЫСТРО!

КАК ПОМЕНЯТЬ КОДИРОВКУ В VISUAL STUDIO CODE С UTF-8 НА 1251 — ПОЧЕМУ VSCODE ГОВНО IDE #04

BLGPG-90F4B1BED0ED-23-10-09-19

Новые материалы:

  • Для ввода пользователем данных с клавиатуры в python используется команда
  • Отключить предупреждения python
  • Pygame или tkinter
  • Даны стороны прямоугольника найти его периметр и длину диагонали python
  • Оператор match в python
  • Python не равно if
  • Python создать список из случайных чисел
  • Python tkinter иконка
  • Python категориальные признаки
  • Python redis примеры
  • Как перевести число в букву python
  • Приложение вконтакте django

I’m trying to convert file content from Windows-1251 (Cyrillic) to Unicode with Python. I found this function, but it doesn’t work.

#!/usr/bin/env python

import os
import sys
import shutil

def convert_to_utf8(filename):
# gather the encodings you think that the file may be
# encoded inside a tuple
encodings = ('windows-1253', 'iso-8859-7', 'macgreek')

# try to open the file and exit if some IOError occurs
try:
    f = open(filename, 'r').read()
except Exception:
    sys.exit(1)

# now start iterating in our encodings tuple and try to
# decode the file
for enc in encodings:
    try:
        # try to decode the file with the first encoding
        # from the tuple.
        # if it succeeds then it will reach break, so we
        # will be out of the loop (something we want on
        # success).
        # the data variable will hold our decoded text
        data = f.decode(enc)
        break
    except Exception:
        # if the first encoding fail, then with the continue
        # keyword will start again with the second encoding
        # from the tuple an so on.... until it succeeds.
        # if for some reason it reaches the last encoding of
        # our tuple without success, then exit the program.
        if enc == encodings[-1]:
            sys.exit(1)
        continue

# now get the absolute path of our filename and append .bak
# to the end of it (for our backup file)
fpath = os.path.abspath(filename)
newfilename = fpath + '.bak'
# and make our backup file with shutil
shutil.copy(filename, newfilename)

# and at last convert it to utf-8
f = open(filename, 'w')
try:
    f.write(data.encode('utf-8'))
except Exception, e:
    print e
finally:
    f.close()

How can I do that?

Thank you

Chilledrat's user avatar

Chilledrat

2,6033 gold badges29 silver badges38 bronze badges

asked Apr 27, 2011 at 15:55

Alex's user avatar

2

import codecs

f = codecs.open(filename, 'r', 'cp1251')
u = f.read()   # now the contents have been transformed to a Unicode string
out = codecs.open(output, 'w', 'utf-8')
out.write(u)   # and now the contents have been output as UTF-8

Is this what you intend to do?

answered Apr 27, 2011 at 16:15

buruzaemon's user avatar

buruzaemonburuzaemon

3,8471 gold badge23 silver badges44 bronze badges

3

This is just a guess, since you didn’t specify what you mean by «doesn’t work».

If the file is being generated properly but appears to contain garbage characters, likely the application you’re viewing it with does not recognize that it contains UTF-8. You need to add a BOM to the beginning of the file — the 3 bytes 0xEF,0xBB,0xBF (unencoded).

answered Apr 27, 2011 at 16:07

Mark Ransom's user avatar

Mark RansomMark Ransom

301k42 gold badges400 silver badges625 bronze badges

0

If you use the codecs module to open the file, it will do the conversion to Unicode for you when you read from the file. E.g.:

import codecs
f = codecs.open('input.txt', encoding='cp1251')
assert isinstance(f.read(), unicode)

This only makes sense if you’re working with the file’s data in Python. If you’re trying to convert a file from one encoding to another on the filesystem (which is what the script you posted tries to do), you’ll have to specify an actual encoding, since you can’t write a file in «Unicode».

answered Apr 27, 2011 at 16:02

Will McCutchen's user avatar

Will McCutchenWill McCutchen

13.1k3 gold badges44 silver badges43 bronze badges

7

Вечно путаюсь в этих кодировках, поэтому решил сделать себе памятку. Покажу на примере.

Итак, кодировка исходного кода задается в первой-второй строке:

#-*-coding: UTF-8 -*-

Далее, допустим мы парсим какой-то сайт в windows-1251:

raw_data = urllib.urlopen(«bla bla bla»).read()

Мы получили данные, и сейчас они находятся в кодировке 1251, а исходник в utf-8, и нам нужно воспользоватся регулярками с кириллицей чтобы что-нибудь найти, выражение:

data = re.findall(r’Данные.*?<.*?>(.*?)<\/>’, raw_data)

выдаст нам пустой массив, потомому что данные в 1251 а регулярка в utf-8. В питоне есть несколько функций для перекодирования:

decode(‘WINDOWS-1251’) — декодирует строку из кодировки 1251 в ЮНИКОД(ЮНИКОД != UTF-8)
encode(‘UTF-8’) — кодирует строку из юникода в UTF-8.

Что касается Юникод vs UTF-8, то:
UNICODE: u’\u041c\u0430\u043c\u0430 \u043c\u044b\u043b\u0430 \u0440\u0430\u043c\u0443′
UTF-8: ‘\xd0\x9c\xd0\xb0\xd0\xbc\xd0\xb0 \xd0\xbc\xd1\x8b\xd0\xbb\xd0\xb0 \xd1\x80\xd0\xb0\xd0\xbc\xd1\x83’
нормальный вид: ‘Мама мыла раму’

Итак, чтобы у нас не было проблем с кодировками, нам достаточно сделать вот так:

raw_data = urllib.urlopen(«bla bla bla»).read().decode(‘WINDOWS-1251’).encode(‘UTF-8’)

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

Специфика работы в Python со строками на русском языке проистекает из того, что существует множество независимых кодировок для представления на компьютере букв, отличных от латинских. Попробуем ответить на вопросы, что такое кодировка символов, почему их так много, и как нам работать с русскими символами и строками в Python.

Вы, конечно, слышали, что все данные в компьютере представлены в цифровом виде. Компьютер в принципе хранит и обрабатывает только числа.

Однако человек работает с текстами, состоящими из букв, цифр, знаков пунктуации и некоторых специальных символов, например, @, #, $. Посмотрите внимательно на символы, из которых состоит текст на экране компьютера. Вы видите их потому, что компьютер, для передачи данных пользователю, представляет хранящиеся в нем числовые данные в виде символов.

И наоборот, для передачи данных в компьютер пользователь вводит символы с клавиатуры. Посмотрите на клавиатуру и найдите кнопки для ввода букв, цифр, знаков пунктуации и специальных символов %, ^ и &. Введенные вами с клавиатуры символы хранятся в памяти компьютера в виде чисел. Потому что ничего, кроме чисел, в компьютере не может храниться.

Поэтому каждый символ, отображаемый или принимаемый компьютером, кодируется некоторым числом. Ниже представлена таблица кодировки ASCII, которая использует числа от 0 до 127 для кодирования символов, включая латиницу (буквы латинского алфавита), цифры от 0 до 9, знаки пунктуации и специальные символы. Кроме того, коды от 0 до 31 кодируют специальные управляющие символы, такие как табуляция TAB, перевод строки LF и другие. Подробнее познакомиться с таблицей ASCII можно в Википедии.

0 NULL 32 Space 64 @ 96 `
1 SOH 33 ! 65 A 97 a
2 STX 34 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 71 G 103 g
8 BS 40 ( 72 H 104 h
9 TAB 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DC1 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 ETB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 124 |
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 ~
31 US 63 ? 95 _ 127 DEL

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

Закодируем, используя приведенную выше таблицу кодов ASCII, слово “Hello”. Мы получим следующую последовательностью числовых кодов: 72, 101, 108, 108, 111. Проверить (и узнать) соответствие букв и кодов можно при помощи встроенных функций Python chr и ord. Функция chr принимает в качестве аргумента целочисленный код и возвращает соответствующий ему символ. Функция ord, наоборот, принимает символ и возвращает кодирующее его целое число:

>>> ord('H')
72
>>> ord('e')
101
>>> chr(101)
'e'
>>> type(chr(101))
<type 'str'>
>>>

Посмотрите еще раз на таблицу ASCII. Как видите, в ней нет букв русского алфавита. А также в ней греческих, арабских, японских и других букв и иероглифов, использующихся в разных языках Земли. Для кодирования букв и других символов, отсутствующих в таблице ASCII, используются числа больше 128. На следующем рисунке представлена кодировка cp866, использующая числа от 128 до 255 для кодирования символов кириллицы (букв русского алфавита) и специальных графических символов.

128 А 160 а 192 224 р
129 Б 161 б 193 225 с
130 В 162 в 194 226 т
131 Г 163 г 195 227 у
132 Д 164 д 196 228 ф
133 Е 165 е 197 229 х
134 Ж 166 ж 198 230 ц
135 З 167 з 199 231 ч
136 И 168 и 200 232 ш
137 Й 169 й 201 233 щ
138 К 170 к 202 234 ъ
139 Л 171 л 203 235 ы
140 М 172 м 204 236 ь
141 Н 173 н 205 237 э
142 О 174 о 206 238 ю
143 П 175 п 207 239 я
144 Р 176 208 240 Ё
145 С 177 209 241 ё
146 Т 178 210 242 Є
147 У 179 211 243 є
148 Ф 180 212 244 Ї
149 Х 181 213 245 ї
150 Ц 182 214 246 Ў
151 Ч 183 215 247 ў
152 Ш 184 216 248 °
153 Щ 185 217 249
154 Ъ 186 218 250 ·
155 Ы 187 219 251
156 Ь 188 220 252
157 Э 189 221 253 ¤
158 Ю 190 222 254
159 Я 191 223 255  

Кодировка cp866 использовалась в операционной системе MS DOS и теперь по умолчанию используется в консоли MS Windows. Буквы cp в названии этой и других кодировок — сокращение от code page (англ.: кодовая страница).

Случилось так, что числа от 128 до 255 стали использоваться в разных странах для кодирования букв алфавитов разных языков, а не только русского. Но даже если вести речь только о кириллице, то, кроме кодировки cp866, существуют несколько других кодировок, которые иначе сопоставляют буквы кириллицы кодам в диапазоне от 128 до 255. В качестве примера еще одной кириллической кодировки ниже приведена таблица кодов cp1251, используемая графическими приложениями в ОС MS Windows, такими как Блокнот, MS Office и другими.

128 Ђ 160   192 А 224 а
129 Ѓ 161 Ў 193 Б 225 б
130 162 ў 194 В 226 в
131 ѓ 163 Ј 195 Г 227 г
132 164 ¤ 196 Д 228 д
133 165 Ґ 197 Е 229 е
134 166 ¦ 198 Ж 230 ж
135 167 § 199 З 231 з
136 168 Ё 200 И 232 и
137 169 © 201 Й 233 й
138 Љ 170 Є 202 К 234 к
139 171 « 203 Л 235 л
140 Њ 172 ¬ 204 М 236 м
141 Ќ 173 ­ 205 Н 237 н
142 Ћ 174 ® 206 О 238 о
143 Џ 175 Ї 207 П 239 п
144 ђ 176 ° 208 Р 240 р
145 177 ± 209 С 241 с
146 178 І 210 Т 242 т
147 179 і 211 У 243 у
148 180 ґ 212 Ф 244 ф
149 181 µ 213 Х 245 х
150 182 214 Ц 246 ц
151 183 · 215 Ч 247 ч
152 ˜ 184 ё 216 Ш 248 ш
153 185 217 Щ 249 щ
154 љ 186 є 218 Ъ 250 ъ
155 187 » 219 Ы 251 ы
156 њ 188 ј 220 Ь 252 ь
157 ќ 189 Ѕ 221 Э 253 э
158 ћ 190 ѕ 222 Ю 254 ю
159 џ 191 ї 223 Я 255 я

Из сказанного можно сделать вывод о том, что для правильного отображения символов на экране компьютеру необходимо знать, в какой кодировке представлены данные, которые нужно отобразить. Например, пускай нам дана следующая последовательность кодов: 232, 227, 226. Если принять, что это символы, представленные в кодировке cp866, то мы получим слово “шут”. А если принять, что это символы, представленные в кодировке cp1251, то мы получим слово “игв”. А в греческой кодировке cp1253 эти же коды дадут нам “θγβ”! На сегодняшний день существуют десятки кодировок, сопоставляющих числовые коды от 128 до 255 различным символам!

Если вы запускаете интерпретатор Python в консоли русскоязычной Windows, то Python ожидает, что строки используют кодировку cp866. Давайте проведем небольшое исследование для того, чтобы подтвердить или опровергнуть это утверждение. Воспользуемся функцией ord для получения числовых кодов нескольких русских букв, введенных с клавиатуры, и таблицей кодов cp866, приведенной выше, чтобы убедиться, что функция ord вернула нам коды букв в кодировке cp866:

>>> print ord('э'), ord('ю'), ord('я')
237 238 239
>>>

А функция chr выведет буквы русского алфавита, соответствующие кодам, взятым нами из таблицы cp866:

>>> print chr(128), chr(129), chr(130)
А Б В
>>>

Итак, русские буквы, которые мы вводим с клавиатуры при работе в интерактивном режиме Python, представлены в кодировке cp866. Работая в интерактивном режиме Python, мы можем смело использовать русские буквы в строковых значениях:

>>> name = 'мир'
>>> print 'Привет', name
Привет мир
>>>

Таким образом, все примеры работы в интерактивном режиме, приведенные в книге, можно безболезненно русифицировать, заменяя английские слова и предложения на русские.

Однако, для русификации скриптов Python, сохраненных в файлах, нам осталось сделать еще один шаг. Нам нужно ответить на вопрос, в какой кодировке сохранен наш скрипт в файле? Это зависит от текстового редактора, в котором был написан и сохранен скрипт, и от того, была ли явно указана кодировка при сохранении файла.

Как было сказано выше, Блокнот, или Notepad, простой текстовый редактор, имеющийся в ОС Windows, использует кириллическую кодировку cp1251, а консоль Windows, или окно для работы с командной строкой, по умолчанию использует кириллическую кодировку cp866. Это очень неудобно для русскоязычных пользователей.

Например, создайте в Блокноте файл C:\russian.txt с единственной строкой:

А теперь откройте окно с командной строкой и выведите содержимое этого файла на экран:

C:\>type russian.txt
╧ЁштхЄ ьшЁ!

Что это за кракозябры?

Если вы отыщете эти символы, один за одним, в приведенной выше таблице кодов cp866, то получится последовательность кодов: 207, 240, 232, 226, 229, 242, 32, 252, 248, 240, 33. (Пробел и восклицательный знак имеют коды из диапазона 0 — 127 и кодируются таблицей ASCII.) Теперь переведите эти коды в символы, используя таблицу кодировки cp1251, и вы получите “Привет мир!” Кракозябры в консольном окне мы видим потому, что Блокнот сохранил файл в кодировке cp1251, а консольное окно считает, что коды от 128 до 255 представляют символы из кодировки cp866!

Преодолеть эту проблему можно с помощью консольной команды chcp. Команда chcp без параметров показывает, какая кодировка является текущей:

C:\>chcp
Active code page: 866

А в качестве параметра команда chcp принимает номер кодировки, которую необходимо сделать текущей. Если с ее помощью изменить текущую кодировку консольного окна на cp1251, то мы, наконец, сможем увидеть содержимое файла russian.txt неискаженным:

C:\>chcp 1251
Active code page: 1251

C:\>type russian.txt
Привет мир!

Скрипт на Python является текстовым файлом точно так же, как файл russian.txt, с которым мы экспериментировали. И если создать и сохранить скрипт, использующий русские буквы, в Блокноте, то скрипт будет сохранен в кодировке cp1251. Давайте откроем в Блокноте файл russian.txt и сохраним его как russian.py, слегка изменив его содержимое:

Теперь это файл с очень простым скриптом на языке Python. Выполним его:

C:\>python russian.py
  File "russian.py", line 1
SyntaxError: Non-ASCII character '\xcf' in file russian.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

Вместо ожидаемого приветствия на русском языке Python вывел сообщение об ошибке. Сообщение говорит о том, что в 1-ой строке файла встретился символ, не являющийся символом ASCII, а кодировка не объявлена. Очевидно, что символы, не являющиеся символами ASCII, в нашем файле — это русские буквы. Но что же в этом плохого?

Дело в том, что Python по умолчанию ожидает, что скрипты, переданные ему для выполнения, имеют кодировку ASCII, то есть, содержат символы с кодами в диапазоне 0 — 127. Для всех, кто использует в своих скриптах только латиницу, цифры и другие символы ASCII, это работает прекрасно. Пользователи, использующие в своих программах строковые значения и комментарии на английском языке, чувствуют себя совершенно комфортно в этой ситуации и, по большей части, не подозревают о проблеме, с которой мы только что столкнулись.

Чтобы сообщить Python о том, что скрипт использует кодировку, отличную от ASCII, нужно в начале файла поместить комментарий специального вида, содержащий информацию о кодировке файла. Для скрипта russian.py, созданного в Блокноте, укажем кодировку cp1251, после чего скрипт будет выглядеть так:

# -*- coding: cp1251 -*-

print 'Привет мир!'

После этого сможем успешно выполнить скрипт в консольном окне Windows (только не забудьте установить текущую кодировку командой chcp 1251):

C:\>chcp 1251
Active code page: 1251

C:\>python russian.py
Привет мир!

Итак, для того, чтобы скрипт Python заговорил по-русски в консольном окне Windows, необходимо:

  1. Указать в начале скрипта кодировку, которую использует файл. Например:

  2. Установить в консольном окне Windows кодировку, которую использует выполняемый скрипт. Например:

    C:\> chcp 1251
    Active code page: 1251

В общем случае, скрипт с русскими строками и комментариями может использовать любую из кириллических кодировок, в частности, любую из рассмотренных выше, cp1251 или cp866. Важно, чтобы объявленная в начале файла кодировка была та самая, в которой сохранен файл.

Если скрипт использует кодировку cp866, то в консольном окне русскоязычной Windows не нужно предпринимать никаких специальных действий перед выполнением скрипта, ведь cp866 — кодировка, установленная в консоли по умолчанию. Но если скрипт использует кодировку cp1251, то перед его выполнением в консоли нужно установить текущую кодировку командой chcp 1251.

  • Кодировка windows 1251 в linux
  • Кодирование windows pcm без сжатия
  • Кодеки для windows 7 x64 последняя версия
  • Кодеки для windows 10 что это
  • Кодеки на микрофон на windows 10