2013-04-07 76 views
0

我不明白这个错误代码。任何人都可以帮我吗?Python Unicode错误信息

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万行代码,您认为这是原因吗?

+1

这意味着该ASCII只能处理低于128的字符值,而'u'\ xE4''是228,这是较大的。鉴于你的标签,你解析一个XML文档吗?那么你可以放弃在源代码中放入'ä'。 – 2013-04-07 09:51:13

+0

你的意思是我的XML的来源? – 2013-04-07 09:58:38

+0

您需要显示引发此错误的代码。你是否保存文件,连接字符串,进行字符串比较,打印到控制台等? – 2013-04-07 10:01:27

回答

3

您正在解析XML,并且该库已知道如何处理您的解码。该API将返回unicode对象,但您试图将它们视为字节字符串。

当你打电话''.format(),您使用的是蟒蛇,而不是字节串一个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的读了起来:由Joel Spolsky的由斯内德尔德

+0

它的工作非常感谢! – 2013-04-07 10:42:34

1

ASCII characters范围从0(\ x00)到127(\ x7F)。你的角色(\ xE4 = 228)大于最高可能值。因此,您必须更改编解码器(例如UTF-8)才能编码此值。

+0

那么我该如何更改编解码器?我是这样一个新手,请帮助 – 2013-04-07 09:58:59

+0

@EdwardOctavianusPakpahan取决于您当前的代码。如果你有'u'\ xe4'.encode('ascii')',只需将'ascii'改为'utf-8'。 – pascalhein 2013-04-07 10:02:03

+0

Im解析一个XML文件,'<?xml version =“1.0”encoding =“UTF-8”?>'我认为它已经在UTF-8中了? – 2013-04-07 10:23:06

3

没有明文这样的东西。文本始终是一种编码,这是您用一系列字节表示给定符号(字母,逗号,日文汉字)的方式。符号“代码”与字节之间的映射称为编码。

在Python 2.7中,编码文本(str)和通用未编码文本(unicode())之间的区别最多是令人困惑的。 python 3放弃了整个事情,并且默认情况下总是使用unicode类型。

在任何情况下,发生的情况是您正在尝试读取一些文本并将其放入字符串中,但是此文本包含的内容不能被强制转换为ASCII编码。 ASCII只能理解0-127范围内的字符,这是标准字符集(字母,数字,用于编程的符号)。 ASCII的一个可能的扩展是拉丁-1(也称为iso-8859-1),其中范围128-255映射到拉丁字符,如重音a。这种编码的优点是你仍然可以得到一个字节==一个字符。 UTF-8是ASCII的另一个扩展,您可以释放约束一个字节==一个字符,并允许一个字符用一个字节表示,一些用两个字符表示,依此类推。

要解决您的问题,这取决于。这取决于问题出在哪里。我猜你正在解析一个文本文件,该文件以某种你不知道的编码进行编码,我猜可能是latin-1或UTF-8。如果你这样做,你必须在open()中打开指定encoding ='utf-8'的文件,但这取决于它。很难从你提供的内容中说出。

+0

+1很好的解释。 – pascalhein 2013-04-07 10:04:31

+0

我正在解析一个XML文件,在XML文件中的代码的顶部,它说'<?xml version =“1.0”encoding =“UTF-8”?>'我假设XML文件已经在UTF-7编码风格?所以如果我需要改变我的代码,那么最好放在哪里? – 2013-04-07 10:24:33

+0

不,不是UTF-7。 UTF-8,这是不同的!无论如何,是的,xml是这样编码的,它确实包含非ascii字符,所以您将需要适当的编解码器。 – 2013-04-07 10:31:01