我不明白这个错误代码。有谁可以帮助我?
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 2:
ordinal not in range(128)
这是代码:
import urllib2, os, zipfile
from lxml import etree
def xmlSplitter(data,separator=lambda x: x.startswith('<?xml')):
buff = []
for line in data:
if separator(line):
if buff:
yield ''.join(buff)
buff[:] = []
buff.append(line)
yield ''.join(buff)
def first(seq,default=None):
"""Return the first item from sequence, seq or the default(None) value"""
for item in seq:
return item
return default
datasrc = "http://commondatastorage.googleapis.com/patents/grantbib/2011/ipgb20110104_wk01.zip"
filename = datasrc.split('/')[-1]
if not os.path.exists(filename):
with open(filename,'wb') as file_write:
r = urllib2.urlopen(datasrc)
file_write.write(r.read())
zf = zipfile.ZipFile(filename)
xml_file = first([ x for x in zf.namelist() if x.endswith('.xml')])
assert xml_file is not None
count = 0
for item in xmlSplitter(zf.open(xml_file)):
count += 1
if count > 10: break
doc = etree.XML(item)
docID = first(doc.xpath('//publication-reference/document-id/doc-number/text()'))
title = first(doc.xpath('//invention-title/text()'))
lastName = first(doc.xpath('//addressbook/last-name/text()'))
firstName = first(doc.xpath('//addressbook/first-name/text()'))
street = first(doc.xpath('//addressbook/address/street/text()'))
city = first(doc.xpath('//addressbook/address/city/text()'))
state = first(doc.xpath('//addressbook/address/state/text()'))
postcode = first(doc.xpath('//addressbook/address/postcode/text()'))
country = first(doc.xpath('//addressbook/address/country/text()'))
print "DocID: {0}\nTitle: {1}\nLast Name: {2}\nFirst Name: {3}\nStreet: {4}\ncity: {5}\nstate: {6}\npostcode: {7}\ncountry: {8}\n".format(docID,title,lastName,firstName,street,city,state,postcode,country)
我在互联网上的某个地方获得了代码,我只更改了其中的一小部分,即增加了街道,城市,州,邮政编码和国家/地区。
XML文件大约包含200万行代码,您认为这是原因吗?
答案 0 :(得分:3)
没有明文这样的东西。文本始终是一种编码,这是您用一系列字节表示给定符号(字母,逗号,日语汉字)的方式。符号“code”与字节之间的映射称为编码。
在python 2.7中,编码文本(str)和通用的未编码文本(unicode())之间的区别最多令人困惑。 python 3抛弃了整个事情,默认情况下你总是使用unicode类型。
在任何情况下,正在发生的事情是你试图读取一些文本并将其放入一个字符串中,但是这个文本包含了一些无法强制转换为ASCII编码的文本。 ASCII只能理解0-127范围内的字符,这是标准的字符集(用于编程的字母,数字,符号)。 ASCII的一个可能的扩展是latin-1(也称为iso-8859-1),其中范围128-255映射到拉丁字符,例如重音a。这种编码的优点是你仍然得到一个字节==一个字符。 UTF-8是ASCII的另一个扩展,你可以释放约束一个字节==一个字符,并允许一些字符用一个字节表示,一些用两个字节表示,依此类推。
要解决您的问题,这取决于。这取决于问题的来源。我猜你正在解析一个用你不知道的编码编码的文本文件,我想这可能是latin-1或UTF-8。如果这样做,你必须在open()中打开指定encoding ='utf-8'的文件,但这取决于。你提供的内容很难说。
答案 1 :(得分:3)
您正在解析XML,并且该库已经知道如何为您处理解码。 API返回 unicode
对象,但您尝试将它们视为字节字符串。
在调用''.format()
的地方,您使用的是python字节字符串而不是unicode
对象,因此Python必须编码 Unicode值以适应字节字符串。为此,它只能使用默认值,即ASCII。
简单的解决方案是在那里使用unicode字符串,注意u''
字符串文字:
print u"DocID: {0}\nTitle: {1}\nLast Name: {2}\nFirst Name: {3}\nStreet: {4}\ncity: {5}\nstate: {6}\npostcode: {7}\ncountry: {8}\n".format(docID,title,lastName,firstName,street,city,state,postcode,country)
Python仍然需要在打印时对其进行编码,但至少现在Python可以对终端进行一些自动检测,并确定需要使用的编码。
您可能想要阅读Python和Unicode:
答案 2 :(得分:1)
ASCII characters范围从0(\ x00)到127(\ x7F)。您的角色(\ xE4 = 228)大于最高可能值。因此,您必须更改编解码器(例如,更改为UTF-8)才能对此值进行编码。