编码解码问题。Python。Django。BeautifulSoup
在这段代码中:
soup=BeautifulSoup(program.Description.encode('utf-8'))
name=soup.find('div',{'class':'head'})
print name.string.decode('utf-8')
当我尝试打印或保存到数据库时出现了错误。
我做什么都没用:
print name.string.encode('utf-8')
或者只是
print name.string
Traceback (most recent call last):
File "./manage.py", line 16, in <module>
execute_manager(settings)
File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/__init__.py", line 362, in execute_manager
utility.execute()
File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/__init__.py", line 303, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/base.py", line 195, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/base.py", line 222, in execute
output = self.handle(*args, **options)
File "/usr/local/cluster/dynamic/website/video/remmedia/management/commands/remmedia.py", line 50, in handle
self.FirstTimeLoad()
File "/usr/local/cluster/dynamic/website/video/remmedia/management/commands/remmedia.py", line 115, in FirstTimeLoad
print name.string.decode('utf-8')
File "/usr/lib/python2.5/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5: ordinal not in range(128)
这是 repr(name.string)
u'\u0412\u044b\u043f\u0443\u0441\u043a \u043e\u0442 27 \u0434\u0435\u043a\u0430\u0431\u0440\u044f'
4 个回答
编辑: name.string
是来自 BeautifulSoup 的,所以它应该已经是一个 Unicode 字符串了。
不过,你的错误信息提到了 'ascii':
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5:
ordinal not in range(128)
根据 PrintFails Python 维基页面,如果 Python 不知道或者无法判断你的输出设备需要什么样的编码,它会把 sys.stdout.encoding
设置为 None
,然后 print
就会尝试用 'ascii' 编码来处理它的参数。
我认为这就是你遇到问题的原因。你可以通过查看 print sys.stdout.encoding
是否输出 None
来确认这一点。
根据上面提到的同一页面,你可以通过明确告诉 Python 使用什么编码来解决这个问题。你可以通过将 sys.stdout
包装在一个 StreamWriter
的实例中来做到这一点:
例如,你可以尝试在 print
语句之前添加:
import sys
import locale
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
到你的脚本中。你可能需要将 locale.getpreferredencoding()
改成一个明确的编码(比如 'utf-8'、'cp1252' 等等)。使用什么编码取决于你的输出设备。它应该设置为你的输出设备所期望的编码。如果你是在终端输出,终端可能有一个菜单设置,允许用户设置终端应该期待什么类型的编码。
原始回答: 尝试:
print name.string
或者
print name.string.encode('utf-8')
你可以试试:
print name.string.encode('ascii', 'replace')
无论sys.stdout
的编码是什么(包括没有编码),输出都应该被接受。
实际上,你打印的这个文件样的对象可能不支持UTF-8编码。举个例子,如果你有一个看起来没什么问题的程序:
# -*- coding: utf-8 -*-
print u"hérisson"
在一个可以打印带重音符号的字符的终端上运行它是没问题的:
lebigot@weinberg /tmp % python2.5 test.py
hérisson
但是如果你把输出打印到一个连接到Unix管道的标准输出上,就会出问题:
lebigot@weinberg /tmp % python2.5 test.py | cat
Traceback (most recent call last):
File "test.py", line 3, in <module>
print u"hérisson"
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 1: ordinal not in range(128)
因为在这种情况下,sys.stdout
的编码是None
,Python认为通过管道读取的程序应该接收ASCII编码,而打印失败是因为ASCII无法表示我们想要打印的那个词。像上面提到的解决方案就能解决这个问题。
注意:你可以用以下方式检查你的标准输出的编码:
print sys.stdout.encoding
这可以帮助你调试编码问题。
我不太明白你想用 name.string.decode('utf-8')
做什么。正如BeautifulSoup的文档所说的那样,“BeautifulSoup给你的是Unicode,真是的”。所以 name.string
其实已经解码了——它是Unicode格式的。如果你想的话,可以把它编码回utf-8,但你不能再进一步解码了。