2013-07-28 21 views
46

ottengo un errore con il seguente scalpiccio:u ' ufeff' in Python stringa

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

Non so cosa u'\ufeff' a dire, si presenta quando sono web scraping. Come posso porre rimedio alla situazione? Il metodo di stringa .replace() non funziona su di esso.

+5

Da dove proviene questo input? Cosa stai cercando di fare? Per favore includi il tuo codice Python. –

+1

Incidentalmente, trovo che .replace() funzioni in python moderno se ricordo l'indicatore unicode: s.replace (u '\ ufeff', '') –

+0

@DougBradshaw quando dici "python moderno", vuoi dire , 2.7+ o 3.0+? – teewuane

risposta

78

Il carattere Unicode U+FEFF è il byte order mark o BOM e viene utilizzato per indicare la differenza tra codifica UTF-16 big e little-endian. Se decodificate la pagina web usando il codec corretto, Python la rimuoverà automaticamente. Esempi:

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

noti che EF BB BF è un BOM UTF-8-encoded. Non è richiesto per UTF-8, ma serve solo come firma (di solito su Windows).

uscita:

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. 

Si noti che il utf-16 codificato richiede BOM di essere presenti, o Python non si sa se i dati sono grande- o little-endian.

2

Questo carattere è lo BOM o "Indicativo byte". Di solito viene ricevuto come i primi pochi byte di un file, che ti dice come interpretare la codifica del resto dei dati. Puoi semplicemente rimuovere il personaggio per continuare. Sebbene, poiché l'errore dice che stavi cercando di convertire in 'ascii', dovresti probabilmente scegliere un'altra codifica per qualsiasi cosa stavi tentando di fare.

-1

In particolare il segno di ordine byte di feff è un indicatore della codifica utf-16. Poiché tutti i byte di utf-16 sono usati raramente, ci sono due diversi schemi di codifica che le persone usano. Dal momento che le diverse codifiche sono fondamentalmente solo sfogliando i byte in utf-16 lo standard è che il Byte Order Mark sarà sempre feff. In questo modo, se qualcuno invia qualcosa all'interno di un Byte Order Mark of ffef, l'encoder unicode sa capovolgere l'ordine di tutti i byte nel documento che segue.

+0

'UTF-16' ha due diverse codifiche: little-endian e big-endian. Il segno di ordine dei byte viene utilizzato per indicare la differenza. –

+2

Si sta descrivendo UTF-16. "Ordine byte" è * irrilevante * in utf-8, perché per definizione utilizza solo codici a 8 bit. Pertanto FEFFh non può mai essere un codice UTF-8 valido. La sua rappresentazione * a 8 bit * (che è lunga 3 byte), ma solo dopo essere stata analizzata in caratteri Unicode. E quindi non ti interesserebbe più qualcosa di basso livello come "ordinamento dei byte". Trovare 0FEFFh (codificato in UTF8) all'inizio di un file UTF-8 altrimenti valido è probabilmente un errore di codifica e può essere tranquillamente ignorato. – usr2564301

4

Il contenuto che stai raschiando è codificato in unicode piuttosto che testo ascii, e stai ricevendo un carattere che non converte in ascii. La "traduzione" giusta dipende da ciò che la pagina web originale pensava che fosse. Python's unicode page fornisce lo sfondo su come funziona.

Stai cercando di stampare il risultato o incollarlo in un file? L'errore suggerisce che è scrivere i dati che stanno causando il problema, non leggerlo. This question è un buon posto per cercare le correzioni.

1

Questo problema sorgono in pratica quando si salva il codice Python in un UTF-8 o UTF-16 perché pitone aggiungere alcuni caratteri speciali all'inizio del codice automatico (che non è dimostrato dai editor di testo) per identificare il formato di codifica. Ma, quando provi ad eseguire il codice, ti dà l'errore di sintassi nella riga 1, inizio del codice perché il compilatore python comprende la codifica ASCII. quando si visualizza il codice del file utilizzando la funzione read() che è possibile visualizzare all'inizio del codice restituito '\ ufeff' viene visualizzato. L'unica soluzione più semplice a questo problema è semplicemente il che modifica la codifica in codifica ASCII (per questo è possibile copiare il codice su un blocco note e salvarlo Ricorda! Scegliere la codifica ASCII ... Spero che questo aiuti.

0

Mi sono imbattuto in questo in Python 3 e ho trovato questa domanda (e solution). Aprendo un file, Python 3 supporta la parola chiave encoding per gestire automaticamente la codifica.

Senza di essa, la distinta è inclusa nel risultato di lettura:

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

Dare la codifica corretta, la distinta viene omesso nel risultato:

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

Solo i miei 2 centesimi.