it-swarm.com.ru

UnicodeDecodeError: кодек "utf8" не может декодировать байт 0x9c

У меня есть сервер сокетов, который должен принимать действительные символы UTF-8 от клиентов.

Проблема заключается в том, что некоторые клиенты (в основном хакеры) отправляют через них все неправильные данные.

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

Иногда я получаю символы вроде этого œ, которые вызывают ошибку UnicodeDecodeError.

Мне нужно иметь возможность сделать строку UTF-8 с или без этих символов.


Обновление:

В моем конкретном случае служба сокетов была MTA, и поэтому я ожидаю только получить команды ASCII, такие как:

EHLO example.com
MAIL FROM: <[email protected]>
...

Я записывал все это в формате JSON.

Тогда некоторые люди без добрых намерений решили продать все виды мусора.

Вот почему в моем конкретном случае вполне нормально удалить не ASCII символы.

203
transilvlad

http://docs.python.org/howto/unicode.html#the-unicode-type

str = unicode(str, errors='replace')

или же

str = unicode(str, errors='ignore')

Примечание: _ ​​Это удалит (игнорирует) символы, возвращающие строку без них.

Для меня это идеальный случай, так как я использую его как защиту от ввода не-ASCII, который не разрешен моим приложением.

Альтернативно: Используйте метод open из модуля codecs , чтобы прочитать в файле:

import codecs
with codecs.open(file_name, "r",encoding='utf-8', errors='ignore') as fdata:
272
transilvlad

Этот тип проблем возник у меня сейчас, когда я перешел на Python 3. Я понятия не имел, что Python 2 просто Steam решает любые проблемы с кодировкой файлов. 

Я нашел это Хорошее объяснение различий и как найти решение после того, как ничего из вышеперечисленного не помогло мне. 

http://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html

Короче говоря, чтобы заставить Python 3 вести себя как можно ближе к использованию Python 2:

with open(filename, encoding="latin-1") as datafile:
    # work on datafile here

Тем не менее, прочитайте статью, там не один размер подходит для всех решений. 

45
James McCormac

Смена движка с C на Python сделала мой трюк.

Двигатель C:

pd.read_csv(gdp_path, sep='\t', engine='c')

Кодек utf-8 не может декодировать байт 0x92 в позиции 18: недопустимый начальный байт

Двигатель Python:

pd.read_csv(gdp_path, sep='\t', engine='python')

Нет ошибок для меня.

37
Doğuş Bıçak
>>> '\x9c'.decode('cp1252')
u'\u0153'
>>> print '\x9c'.decode('cp1252')
œ
26
Ignacio Vazquez-Abrams

У меня была та же проблема с UnicodeDecodeError, и я решил ее с помощью этой строки . Не знаю, является ли это лучшим способом, но это сработало для меня.

str = str.decode('unicode_escape').encode('utf-8')
16
maiky_forrester

На всякий случай у кого-то такая же проблема. Я использую vim с YouCompleteMe , не удалось запустить ycmd с этим сообщением об ошибке, что я сделал: export LC_CTYPE="en_US.UTF-8", проблема исчезла.

2
hylepo

Что вы можете сделать, если вам нужно внести изменения в файл, но вы не знаете кодировку файла? Если вы знаете, что кодировка совместима с ASCII, и хотите проверить или изменить только части ASCII, вы можете открыть файл с помощью обработчика ошибок surrogateescape:

with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
    data = f.read()
0
Kothapati Purandhar Reddy

первый, используя get_encoding_type, чтобы получить тип файла кодирования:

import os    
from chardet import detect

# get file encoding type
def get_encoding_type(file):
    with open(file, 'rb') as f:
        rawdata = f.read()
    return detect(rawdata)['encoding']

во-вторых, открывая файлы с типом:

open(current_file, 'r', encoding = get_encoding_type, errors='ignore')
0
Ivan Lee