python xec UnicodeEncodeError: il codec 'ascii' non può codificare il carattere u '\ xa0' in posizione 20: ordinale non compreso nell'intervallo(128)




unicodeencodeerror ascii codec can t encode character pandas (16)

Sto riscontrando problemi nel trattare con caratteri unicode dal testo recuperato da pagine web diverse (su siti diversi). Sto usando BeautifulSoup.

Il problema è che l'errore non è sempre riproducibile; a volte funziona con alcune pagine e, a volte, barfs lanciando un UnicodeEncodeError . Ho provato praticamente tutto ciò a cui riesco a pensare, eppure non ho trovato nulla che funzioni in modo coerente senza generare qualche tipo di errore relativo a Unicode.

Una delle sezioni di codice che causa problemi è mostrata di seguito:

agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()

Ecco una traccia dello stack prodotta su SOME stringhe quando viene eseguito lo snippet precedente:

Traceback (most recent call last):
  File "foobar.py", line 792, in <module>
    p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)

Sospetto che ciò sia dovuto al fatto che alcune pagine (o più specificamente pagine di alcuni siti) possono essere codificate, mentre altre possono essere non codificate. Tutti i siti sono basati nel Regno Unito e forniscono dati destinati al consumo nel Regno Unito - quindi non ci sono problemi relativi all'internalizzazione o alla gestione di testi scritti in qualcosa di diverso dall'inglese.

Qualcuno ha qualche idea su come risolvere questo in modo che io possa risolvere questo problema in modo coerente?


Sotto la soluzione ha funzionato per me, appena aggiunto

tu "Stringa"

(che rappresenta la stringa come unicode) prima della mia stringa.

result_html = result.to_html(col_space=1, index=False, justify={'right'})

text = u"""
<html>
<body>
<p>
Hello all, <br>
<br>
Here's weekly summary report.  Let me know if you have any questions. <br>
<br>
Data Summary <br>
<br>
<br>
{0}
</p>
<p>Thanks,</p>
<p>Data Team</p>
</body></html>
""".format(result_html)

Semplici funzioni di supporto trovate here .

def safe_unicode(obj, *args):
    """ return the unicode representation of obj """
    try:
        return unicode(obj, *args)
    except UnicodeDecodeError:
        # obj is byte string
        ascii_text = str(obj).encode('string_escape')
        return unicode(ascii_text)

def safe_str(obj):
    """ return the byte string representation of obj """
    try:
        return str(obj)
    except UnicodeEncodeError:
        # obj is unicode
        return unicode(obj).encode('unicode_escape')

In realtà ho scoperto che nella maggior parte dei casi, la semplice rimozione di quei personaggi è molto più semplice:

s = mystring.decode('ascii', 'ignore')

Prova a risolvere questo,

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')

Un sottile problema che causa anche il fallimento della stampa è il fatto che le variabili di ambiente siano impostate in modo errato, ad es. qui LC_ALL è impostato su "C". In Debian si scoraggiano impostandolo: Debian wiki su Locale

$ echo $LANG
en_US.utf8
$ echo $LC_ALL 
C
$ python -c "print (u'voil\u00e0')"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)
$ export LC_ALL='en_US.utf8'
$ python -c "print (u'voil\u00e0')"
voilà
$ unset LC_ALL
$ python -c "print (u'voil\u00e0')"
voilà

Abbiamo manage.py migrate questo errore durante l'esecuzione di manage.py migrate in Django con fixture localizzate.

La nostra fonte conteneva la # -*- coding: utf-8 -*- dichiarazione, MySQL era correttamente configurato per utf8 e Ubuntu aveva il language pack e i valori appropriati in /etc/default/locale .

Il problema era semplicemente che il contenitore Django (noi usiamo la finestra mobile) mancava l'env var LANG .

Impostare LANG su en_US.UTF-8 e riavviare il contenitore prima di rieseguire le migrazioni ha risolto il problema.


Per me, quello che ha funzionato è stato:

BeautifulSoup(html_text,from_encoding="utf-8")

Spero che questo aiuti qualcuno.


Se hai qualcosa come packet_data = "This is data" allora fai questo sulla riga successiva, subito dopo aver inizializzato packet_data :

unic = u''
packet_data = unic

bene ho provato di tutto ma non è stato d'aiuto, dopo aver cercato su google ho capito quanto segue e mi ha aiutato. python 2.7 è in uso.

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')

Questo è un classico punto di dolore unicode di pitone! Considera quanto segue:

a = u'bats\u00E0'
print a
 => batsà

Tutto bene finora, ma se chiamiamo str (a), vediamo cosa succede:

str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)

Oh, tuffo, non andrà bene a nessuno! Per correggere l'errore, codifica i byte esplicitamente con .encode e comunica a python quale codec usare:

a.encode('utf-8')
 => 'bats\xc3\xa0'
print a.encode('utf-8')
 => batsà

Voil \ u00E0!

Il problema è che quando chiamate str (), python usa la codifica dei caratteri di default per provare e codificare i byte che gli avete dato, che nel vostro caso sono a volte rappresentazioni di caratteri unicode. Per risolvere il problema, devi dire a python come gestire la stringa che gli dai usando .encode ('whatever_unicode'). La maggior parte delle volte, dovresti stare bene usando utf-8.

Per un'eccellente esposizione su questo argomento, vedi PyCon di Ned Batchelder parla qui: http://nedbatchelder.com/text/unipain.html


Ho appena usato il seguente:

import unicodedata
message = unicodedata.normalize("NFKD", message)

Controlla cosa dice la documentazione a riguardo:

unicodedata.normalize (form, unistr) Restituisce il modulo di forma normale per la stringa Unicode unistr. I valori validi per il modulo sono 'NFC', 'NFKC', 'NFD' e 'NFKD'.

Lo standard Unicode definisce varie forme di normalizzazione di una stringa Unicode, basate sulla definizione di equivalenza canonica e equivalenza di compatibilità. In Unicode, diversi caratteri possono essere espressi in vari modi. Ad esempio, il carattere U + 00C7 (LETTER CAPITAL LETTER C WITH CEDILLA) può anche essere espresso come la sequenza U + 0043 (LATIN CAPITAL LETTER C) U + 0327 (COMBINAZIONE CEDILLA).

Per ogni carattere, ci sono due forme normali: forma normale C e forma normale D. La forma normale D (NFD) è anche nota come decomposizione canonica e traduce ogni carattere nella sua forma scomposta. La forma normale C (NFC) applica prima una decomposizione canonica, quindi ricompone nuovamente i caratteri pre-combinati.

Oltre a queste due forme, esistono due ulteriori forme normali basate sull'equivalenza di compatibilità. In Unicode, sono supportati alcuni caratteri che normalmente sarebbero unificati con altri caratteri. Ad esempio, U + 2160 (NUMERO ROMANO UNO) è proprio la stessa cosa di U + 0049 (LETTER CAPITAL LETTER I). Tuttavia, è supportato in Unicode per la compatibilità con i set di caratteri esistenti (es. Gb2312).

La normale forma KD (NFKD) applicherà la decomposizione della compatibilità, cioè sostituirà tutti i caratteri di compatibilità con i loro equivalenti. La forma normale KC (NFKC) applica prima la decomposizione della compatibilità, seguita dalla composizione canonica.

Anche se due stringhe Unicode sono normalizzate e sembrano identiche a quelle di un lettore umano, se uno combina caratteri e l'altro no, potrebbero non essere uguali.

Risolve per me. Semplice e facile.


Ho trovato un'elegante soluzione per me per rimuovere i simboli e continuare a mantenere le stringhe come segue:

yourstring = yourstring.encode('ascii', 'ignore').decode('ascii')

È importante notare che l'uso dell'opzione ignora è pericoloso perché elimina automaticamente qualsiasi supporto Unicode (e internazionalizzazione) dal codice che lo utilizza, come si vede qui (convertire unicode):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'

Ecco un rimbalzo di alcune altre cosiddette risposte di "fuoriuscita". Ci sono situazioni in cui semplicemente buttare via i fastidiosi personaggi / archi è una buona soluzione, nonostante le proteste espresse qui.

def safeStr(obj):
    try: return str(obj)
    except UnicodeEncodeError:
        return obj.encode('ascii', 'ignore').decode('ascii')
    except: return ""

Provalo:

if __name__ == '__main__': 
    print safeStr( 1 ) 
    print safeStr( "test" ) 
    print u'98\xb0'
    print safeStr( u'98\xb0' )

risultati:

1
test
98°
98

Suggerimento: potresti invece voler denominare questa funzione in toAscii ? È una questione di preferenza.


Basta aggiungere a una variabile encode ('utf-8')

agent_contact.encode('utf-8')

Metto sempre il codice sotto nelle prime due righe dei file python:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

Aggiungi la riga qui sotto all'inizio del tuo script (o come seconda riga):

# -*- coding: utf-8 -*-

Questa è la definizione della codifica del codice sorgente Python. Maggiori informazioni in PEP 263 .





python-unicode