Найти - Пользователи
Полная версия: Кодировка текста
Начало » Python для новичков » Кодировка текста
1
vuln
Есть система мониторинга который по событию генерирует alert в виде текстовых сообщений
на python(е) я их обрабатываю (отправляю на smpp шлюз), все было хорошо пока не стали появляться сообщения на кириллице, пользователям приходило сообщение в вида
Trouble - Количество свободного места на диске ${VolumeDescription}
попробовал тупо все сообщение открывать в utf8 - тогда при сообщениях на латинице скрипт вылетал с Traceback
UnicodeDecodeError: ‘utf-8’ codec can't decode byte 0xef in position 6: invalid continuation byte
т.е. надо как то обработать обе вида сообщения…
думаю можно вот так
import os, codecs
try:
    f = open('C:\\sms.txt', 'r', encoding='utf8')
    text1 = f.read()
except UnicodeDecodeError:
    f = open('C:\\sms.txt', 'r', encoding='cp1251')
    text1 = f.read()
print(text1)

чувствую это костыль
есть более правильные способы считывания текста с не известной кодировкой ?

прилагаю примеры текстовых сообщений:
py.user.next
vuln
Прикреплённый файлы:
attachment test.rar (342 байта)
>>> with open('sms-uni.txt', encoding='utf-8') as fin:
...     print(fin.read())
... 
test#ciscoXXXX status is Up
>>> with open('sms-utf.txt', encoding='utf-8') as fin:
...     print(fin.read())
... 
LENDSTREAM#Trouble - Количество свободного места на диске ${VolumeDescription} сервера LENDSTREAM составляет ${VolumeSpaceAvailable} из ${VolumeSize}- Lendstream-HDD<1Gb
 
>>>

vuln
пользователям приходило сообщение в вида
Это сообщение, закодированное в utf-8, которое раскодируется в cp1251.
>>> s = 'Количество свободного места на диске'
>>> s.encode('cp1251').decode('utf-8')
'Количество свободного места на диске'
>>>
То есть надо у пользователей настроить раскодирование в utf-8.
Если сообщения приходят в utf-8, то есть вероятность, что там могут быть символы из юникода, которые не представимы в cp1251. Поэтому надо у пользователей настраивать, а не ковертировать utf-8 в cp1251 на входе.
vuln
спасибо за подсказку
не удачный пример привел там обе сообщение в utf-8

>>> with open('C:\\sms\\https\\sms-uni.txt', encoding='utf-8') as fin:
print(fin.read())
Traceback (most recent call last):
File “<pyshell#5>”, line 2, in <module>
print(fin.read())
File “C:\Python34\lib\codecs.py”, line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: ‘utf-8’ codec can't decode byte 0xef in position 15: invalid continuation byte

>>> with open('C:\\sms\\https\\sms-uni.txt', encoding='cp1251') as fin:
print(fin.read())
test#ciscoXXXX привет это я - трабл
>>>
py.user.next
vuln
Есть система мониторинга который по событию генерирует alert в виде текстовых сообщений
Значит, там используется cp1251 всегда. Просто cp1251 и utf-8 совпадают по кодам в пределах ascii. Поэтому тебе кажется, что оно закодировано в utf-8, если на английском, тогда как на самом деле оно всё так же закодировано в cp1251.

То есть либо систему настроить в utf-8 надо, либо в скрипте везде cp1251 использовать. Лучше в utf-8 работать, потому что в питоне принято работать с юникодом, а utf-8 весь юникод покрывает (в отличие от cp1251). Но когда работаешь с utf-8, могут быть проблемы с раскодированием в винде, потому что она всё так же по умолчанию использует кодировку из прошлого века.
vuln
в том то и дело что у меня несколько систем мониторинга каждый отправляет в своем формате, я тоже обеими руками за utf8 но разработчик по пока молчит - вот и приходиться делать костыли
doza_and
vuln
его реально заставить работать ?
Да
vuln
что я делаю не так?
Пытаетесь построить общее решение. Реально на коротких сообщениях нельзя отличить utf-8 от других кодировок. (Т.е. можно сделать сообщения которые валидны в разных кодировках, но выглядят по разному).

Без договоренности о кодировке ничего сделать нельзя.

В вашем случае разумны костыли.
Первый вы уже сделали. Второй способ может быть основан на том, что у вас ограниченное количество типов сообщений. Читайте содержимое как поток байт. Выделите характерные подстроки, и по ним классифицируйте содержимое. Потом выполните decode на основании этих данных.
Еще правильнее не смешивать вывод данных из разных источников, если конечно у вас есть такая возможность.
vuln
спасибо всем , вопрос закрыт
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB