Windows 1251 to utf 8 python

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

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

#-*-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’)

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

У сайта есть:

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

При запуске кода:

response = requests.get('url', headers = {'UserAgent': UserAgent().Chrome})

print(response.text)

Ответ примерно такой:

<font face="Verdana"><font color="#FFFFCC" size="2">Óïðàæíåíèå XXVI/6: ãðóïïèðîâàíèå</font><br>

Если это сохранить при помощи:

with open('1.html', 'w', encoding='utf-8') as file:
    file.write(response.text)

То ничего не изменится.
Если просто, то надо сделать текст читаемым, чтоб при просмотре в bs4 и последующем сохранении в файлы можно было видеть текст в utf-8.
Как быть?


  • Вопрос задан

  • 7967 просмотров

Оказалось что библиотека Requests кодирует данные в кодировку Latin-1(ISO-8859-1), сайт же отправляет данные с кодировкой windows-1251. Получалось что библиотека перекодировала данные сайта в другую кодировку.
Решил так:

sourse = requests.get('url')
sourse.encoding='windows-1251' # Теперь requests отдаёт данные в кодировке windows-1251 которая уже нормально читается

В принципе можно остаться на этой кодировке если при записи в файл указать encoding=’utf-8′
Ну если прям сильно хочется перекодировать в utf-8, можно раскодировать текст в utf-8 а потом закодировать в него

# if text is windows-1251
text = '123 asdasd 55f'
text = encode('utf-8').decode('utf-8')

Пригласить эксперта

Войдите, чтобы написать ответ


  • Показать ещё
    Загружается…

Минуточку внимания

Уведомления

  • Начало
  • » Python для новичков
  • » Как файл в кодировке cp1251 сохранить в utf-8

#1 Ноя. 21, 2008 22:35:02

Как файл в кодировке cp1251 сохранить в utf-8

Проблема в том, что я из интернета загружаю страничку. Она в cp1251. Так как обрабатывать её в этой кодировке довольно проблематично, то её нужно перекодировать в utf-8. Вопрос: как?

Офлайн

  • Пожаловаться

#2 Ноя. 21, 2008 23:12:02

Как файл в кодировке cp1251 сохранить в utf-8

Сохранить в утф или обрабатывать в программе в юникоде?

Офлайн

  • Пожаловаться

#3 Ноя. 21, 2008 23:23:07

Как файл в кодировке cp1251 сохранить в utf-8

text_in_cp1251 = open('cp1251.html', 'rb').read()
text_in_unicode = text_in_cp1251.decode('cp1251')
text_in_utf8 = text_in_unicode.encode('utf8')
open('utf8.html', 'wb').write(text_in_utf8)

RTFM, в конце концов же.

Ведь это так просто.

..bw

Отредактировано (Ноя. 22, 2008 00:18:36)

Офлайн

  • Пожаловаться

#4 Ноя. 22, 2008 02:57:42

Как файл в кодировке cp1251 сохранить в utf-8

bw
Ведь это так просто.

На то я и чайник!

Офлайн

  • Пожаловаться

#5 Ноя. 22, 2008 03:30:53

Как файл в кодировке cp1251 сохранить в utf-8

Alexsss, на то вы чайник, чтобы учиться, а не чтобы перекладывать всю работу на других.

Офлайн

  • Пожаловаться

#6 Ноя. 22, 2008 03:54:18

Как файл в кодировке cp1251 сохранить в utf-8

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

f = file("utf8.html", "wb")
for line in file("cp1251.html", "rb"):
f.write(line.decode('cp1251').encode('utf8'))

P.S. Насколько я помню, open теперь использовать некошерно.

Офлайн

  • Пожаловаться

#8 Ноя. 23, 2008 02:41:48

Как файл в кодировке cp1251 сохранить в utf-8

> то можно использовать текстовой редактор
А еще можно использовать iconv :-).

..bw

Отредактировано (Ноя. 23, 2008 02:42:30)

Офлайн

  • Пожаловаться

#9 Янв. 14, 2011 17:21:55

Как файл в кодировке cp1251 сохранить в utf-8

ZZZ
Или более быстрый и менее затратный для памяти вариант, пригодный для очень больших файлов. Главное, чтобы переносы строк были…

f = file("utf8.html", "wb")
for line in file("cp1251.html", "rb"):
f.write(line.decode('cp1251').encode('utf8'))

P.S. Насколько я помню, open теперь использовать некошерно.

Вообще-то, в последней строке с точность наоборот:

f = file("utf8.html", "wb")
for line in file("cp1251.html", "rb"):
f.write(line.decode('utf8').encode('cp1251'))

По крайней мере, в PortablePython 2.5

Офлайн

  • Пожаловаться

#10 Янв. 14, 2011 17:30:32

Как файл в кодировке cp1251 сохранить в utf-8

-=<fantom>=-, зачем тему поднимать двухлетней давности?

Офлайн

  • Пожаловаться

  • Начало
  • » Python для новичков
  • » Как файл в кодировке cp1251 сохранить в utf-8

Сегодня мы нырнем в пучину одной из самых «волосатых» тем в программировании — кодировку символов. Если вы когда-нибудь видели в консоли надпись Привет! вместо «Привет!», значит, вы уже знакомы с тем, как кодировки могут превратить ваш код в тарабарщину. Но не паникуйте! Мы разберемся, как Python работает с символами, почему ваш текст иногда выглядит как послание инопланетян, и как этого избежать. Вперед, в мир байтов, Unicode и магии преобразований!

Что такое кодировка?

Представьте, что компьютер — это иностранец, который понимает только цифры. Когда вы пишете букву «А», он видит не символ, а число. Кодировка — это словарь, который говорит: «Эй, машина, число 65 — это буква ‘A’, а число 1040 — это русская ‘А'». Без кодировок компьютеры бы просто путали кириллицу с эмодзи 😱.

ASCII — дедушка всех кодировок
В начале времен (в 1960-х) появилась кодировка ASCII. Она использовала 7 бит и могла записать 128 символов: латиницу, цифры и знаки препинания. Но тут возникла проблема: как впихнуть в 128 символов кириллицу, иероглифы или смайлы? Ответ: никак. ASCII — как маленькая квартира: места хватит только для базового набора.

Unicode — спаситель человечества
Чтобы все языки мира уместились в одном «алфавите», создали Unicode — мегасловарь, где каждому символу присвоен уникальный номер (например, U+0410 для «А»). Но как хранить эти номера в памяти? Тут на сцену выходят кодировки вроде UTF-8, UTF-16 и других. Они решают, как превратить номер символа в байты (и обратно).


Python и кодировки

В Python 3 есть два типа данных для работы с текстом и байтами:

  1. str — это строки в Unicode. Они как идеальный переводчик: понимают все языки.

  2. bytes — это «сырые» байты, последовательность чисел от 0 до 255. Они как коробка с пазлами: пока не соберешь, не поймешь, что внутри.

Пример:

text = "Привет, 世界!"  # Это строка (str), Unicode
binary_data = text.encode('utf-8')  # А это байты (bytes): b'\xd0\x9f\xd1\x80...'

Если попытаться вывести binary_data без декодирования, получите нечто вроде b'\xd0\x9f...' — это байты в шестнадцатеричном формате. Чтобы превратить их обратно в текст, нужно правильно выбрать кодировку (как ключ от замка).


UTF-8 и Другие кодировки

UTF-8 — это король современных кодировок. Почему?

  • Он обратно совместим с ASCII: старые тексты работают без проблем.

  • Экономит место: английский текст занимает столько же байт, сколько в ASCII.

  • Поддерживает все символы Unicode, включая эмодзи 🦄.

Другие кодировки:

  • UTF-16 и UTF-32 — используют 2 или 4 байта на символ. Мощно, но расточительно.

  • Windows-1251 (кириллица) и ISO-8859-1 (Европа) — локальные герои, но за пределами своей зоны бесполезны.

  • KOI8-R — ретро-кодировка для русского языка, как виниловая пластинка: редко, но атмосферно.

Проблема: Если открыть файл в неправильной кодировке, текст превратится в кракозябры. Например, русский текст в Windows-1251, прочитанный как ISO-8859-1, станет чем-то вроде «РџСЂРёРІРµС‚!».

Таблица с популярными кодировками, их описанием и примерами использования:

Кодировка Описание Пример использования
ASCII 7-битная кодировка, поддерживает только английский алфавит, цифры и символы. A65, a97
UTF-8 Универсальная кодировка, поддерживает все символы Unicode. Экономит место для ASCII. A65, ЯD0 AF, 😊F0 9F 98 8A
UTF-16 Использует 2 или 4 байта на символ. Подходит для текстов с большим количеством символов за пределами ASCII. A00 41, Я04 2F, 😊D8 3D DE 0A
UTF-32 Использует 4 байта на символ. Простая, но расточительная кодировка. A00 00 00 41, Я00 00 04 2F
Windows-1251 Кодировка для кириллицы, используется в Windows. АC0, ЯDF
ISO-8859-1 Кодировка для западноевропейских языков (латиница). A41, éE9
KOI8-R Кодировка для русского языка, популярная в Unix-системах. АE1, ЯD1
CP866 Кодировка для кириллицы, использовалась в DOS. А80, ЯAF
Shift_JIS Кодировка для японского языка. 82 A0, 83 41
GB2312 Кодировка для китайского языка (упрощенные иероглифы). D6 D0, CE C4
EBCDIC Кодировка, используемая в мейнфреймах IBM. AC1, 0F0

Пояснения к таблице:

  1. ASCII — базовая кодировка, но она не поддерживает кириллицу, иероглифы или эмодзи.

  2. UTF-8 — самая популярная кодировка в современном мире. Она поддерживает все символы Unicode и экономит место для текстов на английском.

  3. UTF-16 и UTF-32 — используются реже, но полезны для специфических задач, где важна простота обработки.

  4. Windows-1251 и KOI8-R — локальные кодировки для русского языка. Если открыть файл в неправильной кодировке, текст превратится в кракозябры.

  5. Shift_JIS и GB2312 — кодировки для азиатских языков. Они поддерживают тысячи иероглифов.

  6. EBCDIC — устаревшая кодировка, но до сих пор используется в некоторых банковских системах.


Примеры использования:

  1. UTF-8:

    text = "Привет, мир! 😊"
    binary = text.encode('utf-8')  # b'\xd0\x9f\xd1\x80...'
    decoded = binary.decode('utf-8')  # "Привет, мир! 😊"
  2. Windows-1251:

    text = "Привет!"
    binary = text.encode('windows-1251')  # b'\xcf\xf0\xe8\xe2\xe5\xf2!'
    decoded = binary.decode('windows-1251')  # "Привет!"
  3. KOI8-R:

    text = "Привет!"
    binary = text.encode('koi8-r')  # b'\xf0\xd2\xc9\xd7\xc5\xd4!'
    decoded = binary.decode('koi8-r')  # "Привет!"

Важно:

  • Всегда указывайте кодировку при работе с файлами или сетевыми запросами.

  • Если вы не уверены в кодировке, попробуйте угадать её с помощью библиотек, например chardet:

    import chardet
    data = b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!'
    result = chardet.detect(data)
    print(result)  # {'encoding': 'utf-8', 'confidence': 0.99}

Байты и строки

Представьте: вы получили сообщение в байтах — b'\xd0\x9f\xd1\x80\xd0\xb8...'. Как понять, что это?

  • Если это русский текст, попробуйте декодировать через utf-8:

    binary_data.decode('utf-8')  # "Привет!"
  • Если декодировать через latin-1, получите «ÐŸÑ€Ð¸…» — типичные кракозябры.

Важно: Байты — это не текст! Это как коробка с зашифрованным посланием. Без правильного «ключа» (кодировки) вы его не прочитаете.

Совет: Всегда явно указывайте кодировку при работе с файлами:

# Открываем файл с указанием кодировки
with open('secret.txt', 'r', encoding='utf-8') as file:
    text = file.read()

Если пропустить encoding, Python использует системную кодировку по умолчанию. На Windows это часто cp1251, и тогда ваш файл в utf-8 превратится в «иероглифы».


Шестнадцатеричные Escape-символы

Иногда Python показывает символы в виде \x41 (для «A») или \u0410 (для «А»). Это шестнадцатеричное представление символов. Например:

  • \x41 — байт 0x41 (65 в десятичной) → символ «A».

  • \u0410 — Unicode-символ с кодом U+0410 → русская «А».

Пример «магии»:

text = "\u0031\u0432\u0430\u043d"  # "1ван"

Это удобно, если нужно вставить символ, которого нет на клавиатуре.


Кодировки в строках

В Python есть префиксы для строк, которые меняют их поведение:

  • b'' — строка байтов: b'hello'.

  • u'' — строка Unicode (в Python 3 это по умолчанию).

  • r'' — «сырая» строка (игнорирует экранирование): r'C:\Users\Хакер'.

Совет: Префикс r спасает, когда нужно использовать обратные слеши без экранирования (например, в регулярных выражениях или путях файлов).


Ошибки кодировки

Когда Python не может преобразовать байты в строку (или наоборот), он выбрасывает ошибку. Самые частые:

  1. UnicodeEncodeError — попытка записать символ, которого нет в целевой кодировке.
    Например, записать русскую «Я» в ASCII (он её не знает).

  2. UnicodeDecodeError — попытка прочитать байты в неправильной кодировке.
    Например, прочитать utf-8 как cp1251.

Решение: Используйте параметр errors:

  • ignore — пропустить недопустимые символы.

  • replace — заменить их на ? (для декодирования) или \ufffd (для кодирования).

  • xmlcharrefreplace — заменить на XML-сущности (например, &#1040; для «А»).

Пример:

text = "Привет, 🐍"
binary = text.encode('ascii', errors='replace')  # b'??????, ?'

Кодировки и Веб

Если вы отправляете данные на сервер или в браузер без указания кодировки, возможны два исхода:

  1. Все работает (если повезет).

  2. Пользователи видят абракадабру и шлют вам гневные письма.

HTTP-заголовки и HTML-теги должны явно указывать кодировку:

<meta charset="UTF-8">

Иначе браузер попытается угадать её, что может привести к «сюрпризам». Например, кириллица может отобразиться как РґРІР° вместо «два».


Забавные факты о кодировках

  • Эмодзи в Unicode — это тоже символы! 🎉 Смайлик «😂» имеет код U+1F602.

  • Самый редкий символU+1F47D (👽). Привет, инопланетяне!

  • Споры о пробеле: В Unicode есть пробелы разной ширины (например, U+2002 — средний пробел). Дизайнеры это оценят.

  • Кодировка EBCDIC, использовавшаяся в мейнфреймах IBM, до сих пор жива в некоторых банковских системах. Это как динозавр в IT-музее.


Философия кодировок

Кодировки — это мосты между людьми и машинами. Они позволяют:

  • Сохранять знания на всех языках.

  • Общаться без границ (даже если ваш друг говорит на китайском, а вы — на суахили).

  • Создавать программы, которые понимают весь мир.

Помните: Неправильная кодировка — как неправильный переводчик на переговорах. Может выйти конфуз!


Заключение: Кодируй с умом, и будет тебе счастье

Теперь вы знаете, что кодировки — это не страшные монстры, а инструменты. Главное — всегда явно указывать, с чем работаете. Используйте UTF-8, проверяйте кодировки файлов и не доверяйте «автоопределению».

И если вы вдруг увидите в консоли Так здорово!, не спешите винить Python. Возможно, вы просто забыли сказать ему: «Эй, это же UTF-8!». Удачи в мире байтов и символов! 😎

#!/usr/bin/python

# -*- coding: utf-8 -*-

import chardet

import Tkinter

from Tkinter import Label

from Tkinter import Tk

from Tkinter import X

from tkFileDialog import askopenfilename

import os

def open_file():

try:

filename = askopenfilename()

f = open(filename, ‘r’).read()

except UnicodeDecodeError:

print «can’t open this file»

else:

try:

encoding = chardet.detect(f)

print encoding

except UnicodeDecodeError:

print(‘can\’t detect encoding’)

else:

if encoding[‘encoding’] == ‘ascii’:

print ‘Encoding is: ascii’

elif encoding[‘encoding’] == ‘windows-1251’:

res.configure(text=«Encoding is: windows-1251», fg=«blue»)

elif encoding[‘encoding’] == ‘utf-8’:

res.configure(text=«Encoding is: utf-8», fg=«blue»)

elif encoding[‘encoding’] == ‘None’:

res.configure(text=«Encoding is: None», fg=«blue»)

else:

res.configure(text=‘Encoding can\’t be detected’, fg=«blue»)

print ‘Encoding can\’t be detected’

def convert_from_windows_1251():

filename = askopenfilename()

try:

f = open(filename, ‘r’).read()

except UnicodeDecodeError:

print «it was not a windows-1251 unicode»

else:

try:

unicode_text = f.decode(‘cp1251’)

except UnicodeDecodeError:

print(‘unicode error, trying different encoding’)

else:

abs_path = os.path.join(os.path.dirname(__file__), ‘output_from_cp1251_to_utf8.txt’)

text_in_1251 = unicode_text.encode(‘utf-8’)

f = open(abs_path, ‘w’)

f.write(text_in_1251)

def convert_from_utf8_to_windows_1251():

filename = askopenfilename()

try:

f = open(filename, ‘r’).read()

except UnicodeDecodeError:

print «it was not a utf-8 unicode»

else:

try:

unicode_text = f.decode(‘utf-8’)

except UnicodeDecodeError:

print(‘unicode error, trying different encoding’)

else:

abs_path = os.path.join(os.path.dirname(__file__), ‘output_from_utf8_to_cp1251.txt’)

text_in_1251 = unicode_text.encode(‘cp1251’)

f = open(abs_path, ‘w’)

f.write(text_in_1251)

root = Tk()

root.title(‘UTF-8 Converter’)

root.geometry(‘250×250+500+300’)

root.config(background=«#FFFFFF»)

button = Tkinter.Button(root, text=«Check encoding», width=25, bg=«#FFFFFF», command=open_file)

button.pack(fill=X, padx=10, pady=20)

res = Label(root, bg=«#FFFFFF»)

res.pack()

button1 = Tkinter.Button(root, text=«Convert from windows-1251 to utf-8», width=25, bg=«#FFFFFF»,

command=convert_from_windows_1251)

button1.pack(fill=X, padx=10, pady=15)

button1 = Tkinter.Button(root, text=«Convert from utf-8 to windows-1251», width=25, bg=«#FFFFFF»,

command=convert_from_utf8_to_windows_1251)

button1.pack(fill=X, padx=10, pady=15)

exit_button = Tkinter.Button(root, text=‘Quit’, command=root.destroy, bg=«#FFFFFF»)

exit_button.pack(side=‘bottom’)

root.mainloop()

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Windows 7 медленно работает rdp
  • Hp laserjet p2015 драйвер windows 10 x64
  • Обои 1680 1050 windows
  • Программа для смены стиля windows
  • Как отключить брандмауэр на компьютере windows 7