Подтвердить что ты не робот

U '\ ufeff' в строке Python

Я получаю сообщение об ошибке со следующим сообщением:

UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128)

Не уверен, что такое u'\ufeff', оно появляется, когда я читаю веб-страницы. Как я могу исправить ситуацию? Строковый метод .replace() не работает.

4b9b3361

Ответ 1

Символ Юникода U+FEFF является значком байтового байта или спецификацией и используется для указания разницы между big- и кодировкой маленького конца UTF-16. Если вы декодируете веб-страницу с помощью правильного кодека, Python удалит ее для вас. Примеры:

#!python2
#coding: utf8
u = u'ABC'
e8 = u.encode('utf-8')        # encode without BOM
e8s = u.encode('utf-8-sig')   # encode with BOM
e16 = u.encode('utf-16')      # encode with BOM
e16le = u.encode('utf-16le')  # encode without BOM
e16be = u.encode('utf-16be')  # encode without BOM
print 'utf-8     %r' % e8
print 'utf-8-sig %r' % e8s
print 'utf-16    %r' % e16
print 'utf-16le  %r' % e16le
print 'utf-16be  %r' % e16be
print
print 'utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8')
print 'utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig')
print 'utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16')
print 'utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le')

Обратите внимание, что EF BB BF представляет собой спецификацию с кодировкой UTF-8. Это не требуется для UTF-8, но служит только как подпись (обычно в Windows).

Выход:

utf-8     'ABC'
utf-8-sig '\xef\xbb\xbfABC'
utf-16    '\xff\xfeA\x00B\x00C\x00'    # Adds BOM and encodes using native processor endian-ness.
utf-16le  'A\x00B\x00C\x00'
utf-16be  '\x00A\x00B\x00C'

utf-8  w/ BOM decoded with utf-8     u'\ufeffABC'    # doesn't remove BOM if present.
utf-8  w/ BOM decoded with utf-8-sig u'ABC'          # removes BOM if present.
utf-16 w/ BOM decoded with utf-16    u'ABC'          # *requires* BOM to be present.
utf-16 w/ BOM decoded with utf-16le  u'\ufeffABC'    # doesn't remove BOM if present.

Обратите внимание, что для кодека utf-16 требуется наличие спецификации, или Python не будет знать, являются ли данные big- или little-endian.

Ответ 2

Я столкнулся с этим на Python 3 и нашел этот вопрос (и решение). При открытии файла Python 3 поддерживает ключевое слово кодирования для автоматической обработки кодировки.

Без него спецификация включается в результат чтения:

>>> f = open('file', mode='r')
>>> f.read()
'\ufefftest'

Предоставляя правильное кодирование, спецификация в результате не указывается:

>>> f = open('file', mode='r', encoding='utf-8-sig')
>>> f.read()
'test'

Только мои 2 цента.

Ответ 3

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

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

Ответ 4

Этот символ является спецификацией или "Байт заказа". Он обычно принимается как первые несколько байтов файла, рассказывая вам, как интерпретировать кодировку остальных данных. Вы можете просто удалить символ для продолжения. Хотя, поскольку ошибка говорит о том, что вы пытаетесь преобразовать в ascii, вы, вероятно, должны выбрать другую кодировку для того, что вы пытались сделать.

Ответ 5

Эта проблема возникает в основном при сохранении кода python в кодировке UTF-8 или UTF-16, потому что python автоматически добавляет специальный символ в начале кода (что не показано текстовые редакторы) для определения формата кодирования. Но когда вы пытаетесь выполнить код, он дает вам синтаксическую ошибку в строке 1, то есть начало кода, потому что компилятор python понимает кодировку ASCII. при просмотре кода файла с помощью функции read(), которую вы можете увидеть в начале возвращаемого кода '\ ufeff'. Самое простое решение этой проблемы - просто изменить кодировку обратно на кодировку ASCII (для этого вы можете скопировать код в блокнот и сохранить его. Помните! Выберите кодировку ASCII... Надеюсь, это поможет.

Ответ 6

В python 3.5 он также отлично работает, и не только с ascii:

>>> s = u"Путин - хуйло!\ufeff\n"
>>> print(repr(s))
'Путин - хуйло!\ufeff\n'
>>> s = s.replace(u'\ufeff','')
>>> print (repr(s))
'Путин - хуйло!\n'

Ответ 7

В частности, знак порядка байтов feff является индикатором кодирования utf-16. Поскольку все байты utf-16 используются редко, существуют две разные схемы кодирования, которые используют люди. Поскольку различные кодировки в основном просто перевертывают байты в utf-16, стандарт заключается в том, что знак байтового байта всегда будет feff. Таким образом, если кто-то отправляет что-то с отметкой байтового кода ffef, кодировщик юникода знает, чтобы перевернуть порядок всех байтов в последующем документе.