2013-05-12 16 views
32

Sto creando un file XML in Python e c'è un campo sul mio XML che ho inserito il contenuto di un file di testo. Lo faccio daUnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xc2

f = open ('myText.txt',"r") 
data = f.read() 
f.close() 

root = ET.Element("add") 
doc = ET.SubElement(root, "doc") 

field = ET.SubElement(doc, "field") 
field.set("name", "text") 
field.text = data 

tree = ET.ElementTree(root) 
tree.write("output.xml") 

E poi ho il UnicodeDecodeError. Ho già provato a inserire il commento speciale # -*- coding: utf-8 -*- in cima al mio script ma ho ancora ricevuto l'errore. Inoltre ho provato già ad applicare la codifica della mia variabile data.encode('utf-8') ma ho ancora ricevuto l'errore. So che questo problema è molto comune ma tutte le soluzioni che ho ricevuto da altre domande non hanno funzionato per me.

UPDATE

Traceback: Utilizzando solo il commento speciale sulla prima riga dello script

Traceback (most recent call last): 
    File "D:\Python\lse\createxml.py", line 151, in <module> 
    tree.write("D:\\python\\lse\\xmls\\" + items[ctr][0] + ".xml") 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 820, in write 
    serialize(write, self._root, encoding, qnames, namespaces) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 939, in _serialize_xml 
    _serialize_xml(write, e, encoding, qnames, None) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 939, in _serialize_xml 
    _serialize_xml(write, e, encoding, qnames, None) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 937, in _serialize_xml 
    write(_escape_cdata(text, encoding)) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 1073, in _escape_cdata 
    return text.encode(encoding, "xmlcharrefreplace") 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 243: ordina 
l not in range(128) 

Traceback: Usando .encode('utf-8')

Traceback (most recent call last): 
    File "D:\Python\lse\createxml.py", line 148, in <module> 
    field.text = data.encode('utf-8') 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 227: ordina 
l not in range(128) 

ho usato .decode('utf-8') e il messaggio di errore non è comparso e ha creato correttamente il mio file XML. Ma il problema è che l'XML non è visualizzabile sul mio browser.

+1

Sarebbe utile vedere l'intero messaggio di errore per vedere da dove proviene. Nel frattempo prova a usare 'decode' invece di' encode'. –

+0

Aggiornato, ha creato con successo il mio XML quando uso 'decode', ma il file non è visualizzabile sul mio browser. –

+2

Si noti che l'uso di '# - * - coding: utf-8 - * -' serve solo per inserire caratteri non ASCII nei sorgenti python. Non ha alcun effetto sulla codifica/decodifica delle stringhe in alcun modo. Inoltre, se il file 'myText.txt' non è ASCII dovresti usare' codecs.open' e fornire la giusta codifica: 'codecs.open ('myText.txt', 'r', 'utf-8')' . – Bakuriu

risposta

56

È necessario decodificare i dati dalla stringa di input in unicode, prima di utilizzarli, per evitare problemi di codifica.

field.text = data.decode("utf8") 
12

Si è verificato un errore simile in pywikipediabot. Il metodo .decode è un passo nella giusta direzione, ma per me non ha funzionato senza l'aggiunta di 'ignore':

fix_encoding = lambda s: s.decode('utf8', 'ignore') 
+10

Ricorda che ignorare gli errori di codifica potrebbe potenzialmente perdere dati o produrre risultati errati. – tripleee

6

Python 2

L'errore è causato perché ElementTree non si aspettava di trovare non Le stringhe ASCII impostano l'XML quando provano a scriverlo. Dovresti usare invece le stringhe Unicode per non-ASCII. Le stringhe Unicode possono essere create utilizzando il prefisso u su stringhe, ad esempio u'€' o decodificando una stringa con mystr.decode('utf-8') utilizzando la codifica appropriata.

La migliore pratica è quella di decodificare tutti i dati di testo come letti, piuttosto che decodificare il programma centrale. Il modulo io fornisce un metodo open() che decodifica i dati di testo in stringhe Unicode durante la lettura.

ElementTree sarà molto più felice con Unicode e lo codificherà correttamente correttamente quando si utilizza il metodo ET.write().

Inoltre, per garantire la migliore compatibilità e leggibilità, assicurarsi che ET codifichi su UTF-8 durante write() e aggiunga l'intestazione pertinente.

Presumendo il file di input è codifica UTF-8 (0xC2 è comune UTF-8 piombo byte), mettendo tutto insieme, e utilizzando l'istruzione with, il codice dovrebbe assomigliare:

with io.open('myText.txt', "r", encoding='utf-8') as f: 
    data = f.read() 

root = ET.Element("add") 
doc = ET.SubElement(root, "doc") 

field = ET.SubElement(doc, "field") 
field.set("name", "text") 
field.text = data 

tree = ET.ElementTree(root) 
tree.write("output.xml", encoding='utf-8', xml_declaration=True) 

uscita:

<?xml version='1.0' encoding='utf-8'?> 
<add><doc><field name="text">data€</field></doc></add> 
3

#!/usr/bin/python

# encoding=utf8

Provalo all'inizio del file python

Problemi correlati