UnicodeEncodeError:'ascii'编解码器无法在位置0编码字符u'\ xef':序数不在范围内(128)


75

我想解析我的XML文档。所以我将我的XML文档存储如下

class XMLdocs(db.Expando):  
   id = db.IntegerProperty()    
   name=db.StringProperty()  
   content=db.BlobProperty()  

现在我的下面是我的代码

parser = make_parser()     
curHandler = BasketBallHandler()  
parser.setContentHandler(curHandler)  
for q in XMLdocs.all():  
        parser.parse(StringIO.StringIO(q.content))

我低于错误

'ascii' codec can't encode character u'\xef' in position 0: ordinal not in range(128)
Traceback (most recent call last):  
  File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 517, in __call__
    handler.post(*groups)   
  File "/base/data/home/apps/parsepython/1.348669006354245654/mapreduce/base_handler.py", line 59, in post
    self.handle()   
  File "/base/data/home/apps/parsepython/1.348669006354245654/mapreduce/handlers.py", line 168, in handle
    scan_aborted = not self.process_entity(entity, ctx)   
  File "/base/data/home/apps/parsepython/1.348669006354245654/mapreduce/handlers.py", line 233, in process_entity
    handler(entity)   
  File "/base/data/home/apps/parsepython/1.348669006354245654/parseXML.py", line 71, in process
    parser.parse(StringIO.StringIO(q.content))   
  File "/base/python_runtime/python_dist/lib/python2.5/xml/sax/expatreader.py", line 107, in parse
    xmlreader.IncrementalParser.parse(self, source)   
  File "/base/python_runtime/python_dist/lib/python2.5/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)  
  File "/base/python_runtime/python_dist/lib/python2.5/xml/sax/expatreader.py", line 207, in feed
    self._parser.Parse(data, isFinal)   
  File "/base/data/home/apps/parsepython/1.348669006354245654/parseXML.py", line 136, in characters   
    print ch   
UnicodeEncodeError: 'ascii' codec can't encode character u'\xef' in position 0: ordinal not in range(128)   

2
您的stacktrace显示执行代码与您粘贴的代码不同-并且您正在使用print。不要在WSGI应用程序中使用打印!
尼克·约翰逊,

Answers:


30

看来您要达到UTF-8字节顺序标记(BOM)。尝试使用此Unicode字符串并提取出BOM:

import codecs

content = unicode(q.content.strip(codecs.BOM_UTF8), 'utf-8')
parser.parse(StringIO.StringIO(content))

我使用strip而不是lstrip因为在您的情况下您可能多次出现BOM表,这可能是由于串联的文件内容引起的。


我已经完全按照答案中的说明进行操作,但是遇到了上述错误,首先是给我所提到的位置0,现在它给了我在先前评论中提到的位置5785
mahesh

我建议使用转换s产生错误的任何字符串s = unicode(s.strip(codecs.BOM_UTF8), 'utf-8')s指的是您的字符串名称。
Tugrul Ates

尝试替换lstripstrip
Tugrul Ates

我了解您的建议,并且我也做了同样的错误(详细):ascii编解码器无法在位置5785处编码字符u'\ xef':序数不在range(128)中
mahesh

1
在打印过程中将unicode转换为字符串期间,这是一个编码错误。它不会包含UTF-8 BOM,也无法解码回unicode,并且错误是因为它包含非ASCII字符-删除它们会破坏内容,并且BOM仅是其中之一。
Rosh Oxymoron

112

对于此问题的实际最佳答案取决于您的环境,尤其是终端期望的编码。

最快的单行解决方案是将您打印的所有内容编码为ASCII,您的终端几乎肯定会接受它,同时丢弃无法打印的字符:

print ch #fails
print ch.encode('ascii', 'ignore')

更好的解决方案是将终端的编码更改为utf-8,并在打印之前将所有内容编码为utf-8。每次打印或读取字符串时,都应该养成思考Unicode编码的习惯。


1
就我而言,我正在将Twitter流打印到终端上,并且工作正常。然后我想将程序输出重定向到文件,我开始使用'ascii'编解码器无法对位置32-36中的字符进行编码。后来,像在这个答案中一样,我使用了print tweet.encode(“ utf-8”,ignore),并且一切正常。
kommradHomer 2014年

57

只需将.encode('utf-8')对象放在末尾即可在最新版本的Python中完成这项工作。


3
“最新版本的Python”是什么意思?只有3.x,或也2.7
kramer65

1
Python 2.7显然是最新的,因为它仍在广泛使用。
tmthyjames 2016年

1
适用于我的Python 2.7
A Star


8

根据您的追溯问题是的print第136行的语句parseXML.py。不幸的是,您认为不适合在代码的那部分发布,但是我猜想它仅用于调试。如果将其更改为:

print repr(ch)

那么您至少应该看到要打印的内容。


2
-1为非unicode解决方案提供了一个明显的unicode编码问题。
三联画

7
unicode编码问题与print语句有关。是的,可能还有其他问题,但是解决打印不崩溃是当前的问题。
邓肯

7

问题是您试图将Unicode字符打印到可能是非Unicode的终端。'replace在打印之前,您需要使用选项对它进行编码,例如print ch.encode(sys.stdout.encoding, 'replace')


打印不是必不可少的,对我来说出错的主要陈述是分析陈述
mahesh

3
@Mahesh:是导致问题的原因是您的代码,位于parseXML.py的第136行–您可以自行修复,或向我们展示代码的那一部分,以便我们为您提供帮助。
约翰·马钦

-1

解决此问题的一种简单方法是将默认编码设置为utf8。跟随是一个例子

import sys

reload(sys)
sys.setdefaultencoding('utf8')


你能解释原因吗?
Shafiq

我的评论中有一个链接对此进行了解释。本质上,库希望默认值ascii保持默认值。这就是为什么setdefaultencoding没有reload技巧通常无法获得的原因。
Mark Tolonen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.