2013-07-28 12 views
46

pojawia się błąd z następującym wzorcu:u „ ufeff” w Pythonie ciąg

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

Nie wiesz co u'\ufeff' jest, to pokazuje się, kiedy jestem web skrobanie. Jak mogę zaradzić tej sytuacji? Metoda łańcuchowa .replace() nie działa na nim.

+5

Skąd pochodzą te dane wejściowe? Co próbujesz zrobić? Proszę podać swój kod Pythona. –

+1

Nawiasem mówiąc, uważam, że .replace() działa we współczesnym pythonie, jeśli pamiętam wskaźnik Unicode: s.replace (u '\ ufeff', '') –

+0

@DougBradshaw kiedy mówisz "nowoczesny python", masz na myśli 2,7+ lub 3,0+? – teewuane

Odpowiedz

78

Znak Unicode U+FEFF jest znacznikiem kolejności bajtów lub BOM i służy do odróżnienia dużego i małego endianowania kodowania UTF-16. Jeśli odszyfrujesz stronę przy użyciu właściwego kodera-dekodera, Python ją usunie. Przykłady:

#!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') 

Należy pamiętać, że EF BB BF jest BOMem kodowanym w UTF-8. Nie jest wymagany w przypadku UTF-8, ale służy tylko jako podpis (zazwyczaj w systemie Windows).

wyjściowa:

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. 

Zauważ, że utf-16 kodowane wymaga BOM może być obecny, lub Python nie będą wiedzieć, czy dane są big- lub little-endian.

2

Ta postać to BOM lub "Znak porządku bajtów". Jest zwykle odbierany jako pierwsze kilka bajtów pliku, informując o tym, jak interpretować kodowanie pozostałych danych. Możesz po prostu usunąć postać, aby kontynuować. Chociaż, ponieważ błąd mówi, że próbujesz przekonwertować na "ascii", prawdopodobnie powinieneś wybrać inne kodowanie dla tego, co próbujesz zrobić.

-1

W szczególności znak kolejności bajtów z feff jest wskaźnikiem kodowania utf-16. Ponieważ wszystkie bajty z utf-16 są rzadko używane, istnieją dwa różne schematy kodowania, z których korzystają ludzie. Ponieważ różne kodowania polegają na zwykłym przerzuceniu bajtów w utf-16, standardem jest to, że znak kolejności bajtów zawsze będzie feff. W ten sposób, jeśli ktoś wyśle ​​coś ze znacznikiem kolejności bajtów, koder Unicode wie, że kolejność wszystkich bajtów w kolejnym dokumencie jest odwrócona.

+0

'UTF-16' ma dwa różne kodowania: little-endian i big-endian. Oznaczenie kolejności bajtów służy do odróżnienia. –

+2

Opisujesz UTF-16. "Kolejność bajtów" jest * nieistotna * w utf-8, ponieważ z definicji używa tylko 8-bitowych kodów. Dlatego FEFFh nie może być nigdy poprawnym kodem UTF-8. Jego 8-bitowa * reprezentacja * może (która ma 3 bajty), ale tylko po tym, jak została sparsowana na znaki Unicode. A potem nie byłbyś już zainteresowany czymś tak niskim, jak "porządkowanie bajtów". Odnalezienie wartości 0FFFFh (zakodowanej w UTF8) na początku prawidłowego pliku UTF-8 jest prawdopodobnie błędem kodowania i można go bezpiecznie zignorować. – usr2564301

4

Treści, które zgarniasz, są zakodowane w formacie Unicode, a nie w formacie ASCII. Otrzymujesz postać, która nie konwertuje się na ASCII. Prawidłowe "tłumaczenie" zależy od tego, na co uważała oryginalna strona internetowa. Python's unicode page podaje tło tego, jak działa.

Próbujesz wydrukować wynik lub umieścić go w pliku? Błąd sugeruje, że jest to dane, które powodują problem, a nie jego odczytanie. This question to dobre miejsce do wyszukiwania poprawek.

1

Ten problem powstaje w zasadzie po zapisaniu kodu Pythona w UTF-8 lub UTF-16 kodowania bo python dodać jakiś szczególny charakter na początku automatycznie kodu (co nie jest pokazane przez edytorów tekstu) do zidentyfikować format kodowania. Ale kiedy spróbujesz wykonać kod, daje on błąd składni w wierszu 1, tj. Początek kodu, ponieważ kompilator python rozumie kodowanie ASCII. podczas przeglądania kodu pliku przy użyciu funkcji read(), którą można zobaczyć na początku zwróconego kodu, pojawi się "\ uffff". Najprostszym rozwiązaniem tego problemu jest po prostu zmiana kodowania z powrotem na kodowanie ASCII (możesz skopiować swój kod do notatnika i zapisać go Zapamiętaj! Wybierz kodowanie ASCII ... Mam nadzieję, że to pomoże.

0

Wpadłem na to na Pythonie 3 i znalazłem to pytanie (i solution). Podczas otwierania pliku Python 3 obsługuje słowo kluczowe kodowania, aby automatycznie obsługiwać kodowanie.

Bez niego BOM jest wliczone w Odczytać wynik:

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

Podając odpowiednie kodowanie, BOM zostanie pominięty w wyniku:

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

Tylko moje 2 centy.

Powiązane problemy