u'\ufeff' en una cadena de Python
Recibí un error con el siguiente mensaje de excepción:
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in
position 155: ordinal not in range(128)
No estoy seguro de qué u'\ufeff'
es, aparece cuando estoy haciendo web scraping. ¿Cómo puedo remediar la situación? El .replace()
método de cadena no funciona en él.
Me encontré con esto en Python 3 y encontré esta pregunta (y solución ). Al abrir un archivo, Python 3 admite la palabra clave de codificación para manejar automáticamente la codificación.
Sin él, la lista de materiales se incluye en el resultado de la lectura:
>>> f = open('file', mode='r')
>>> f.read()
'\ufefftest'
Al proporcionar la codificación correcta, la lista de materiales se omite en el resultado:
>>> f = open('file', mode='r', encoding='utf-8-sig')
>>> f.read()
'test'
Sólo mis 2 centavos.
El carácter Unicode U+FEFF
es la marca de orden de bytes, o BOM, y se utiliza para diferenciar entre la codificación UTF-16 big y little-endian. Si decodifica la página web usando el códec correcto, Python la eliminará por usted. Ejemplos:
#!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')
Tenga en cuenta que EF BB BF
es una lista de materiales codificada en UTF-8. No es necesario para UTF-8, pero sirve sólo como firma (normalmente en Windows).
Producción:
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.
Tenga en cuenta que el utf-16
códec requiere que BOM esté presente, o Python no sabrá si los datos son big-o little-endian.
Ese carácter es la BOM o "Marca de orden de bytes". Por lo general, se recibe como los primeros bytes de un archivo y le indica cómo interpretar la codificación del resto de los datos. Simplemente puedes eliminar el personaje para continuar. Aunque, dado que el error dice que estabas intentando convertir a 'ascii', probablemente deberías elegir otra codificación para lo que sea que estuvieras intentando hacer.