2013-05-12 2 views
32

Я создаю XML-файл в Python, и на моем XML-поле есть поле, в которое я помещаю содержимое текстового файла. Я делаю этоUnicodeDecodeError: кодек ascii не может декодировать байт 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") 

И тогда я получаю UnicodeDecodeError. Я уже пробовал поставить специальный комментарий # -*- coding: utf-8 -*- поверх моего скрипта, но все еще получил ошибку. Кроме того, я уже пытался применить кодировку моей переменной data.encode('utf-8'), но все еще получил ошибку. Я знаю, что эта проблема очень распространена, но все решения, которые я получил от других вопросов, не работали для меня.

UPDATE

Traceback: Использование только специальный комментарий на первой строке сценария

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: Использование .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) 

я использовал .decode('utf-8') и сообщение об ошибке не появился, и он успешно создал мой XML-файл. Но проблема в том, что XML не доступен для просмотра в моем браузере.

+1

Было бы полезно увидеть все сообщение об ошибке, чтобы узнать, откуда оно взялось. Тем временем попробуйте использовать 'decode' вместо' encode'. –

+0

Обновлено, он успешно создал мой XML, когда я использую 'decode', но файл не доступен для просмотра в моем браузере. –

+2

Обратите внимание, что использование '# - * - кодирования: utf-8 - * -' служит только для вставки символов не ASCII в источники python. Это никак не влияет на кодирование/декодирование строк. Кроме того, если файл 'myText.txt' не является ASCII, вы должны использовать' codecs.open' и предоставить правильную кодировку: 'codecs.open ('myText.txt', 'r', 'utf-8')' , – Bakuriu

ответ

56

Чтобы избежать проблем с кодировкой, вам необходимо декодировать данные из входной строки в unicode перед ее использованием.

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

Я столкнулся с аналогичной ошибкой в ​​pywikipediabot. Метод .decode является шагом в правильном направлении, но для меня это не работает без добавления 'ignore':

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

Обратите внимание, что игнорирование ошибок кодирования потенциально может потерять данные , или произвести неправильный вывод. – tripleee

6

Python 2

вызвана ошибка, потому что ElementTree не ожидал найти не- Строки ASCII задают XML при попытке записать его. Вместо этого вы должны использовать строки Unicode для не-ASCII. Строки Unicode могут быть сделаны либо с использованием префикса u на строках, то есть u'€', либо путем декодирования строки с помощью mystr.decode('utf-8') с использованием соответствующей кодировки.

Лучшей практикой является декодирование всех текстовых данных по мере их чтения, а не декодирование средней программы. Модуль io предоставляет метод open(), который декодирует текстовые данные в строки Unicode по мере их чтения.

ElementTree будет намного счастливее с Unicodes и будет правильно кодировать его правильно при использовании метода ET.write().

Кроме того, для обеспечения лучшей совместимости и удобочитаемости убедитесь, что ET кодирует UTF-8 во время write() и добавляет соответствующий заголовок.

Предположив входной файл является UTF-8 кодируется (0xC2 общие UTF-8 ведущих байт), положить все вместе, и используя with заявление, ваш код должен выглядеть следующим образом:

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) 

Выход:

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

#!/usr/bin/python

# encoding=utf8

Попробуйте это для запуска файла python

Смежные вопросы