编码解码问题。Python。Django。BeautifulSoup

0 投票
4 回答
5801 浏览
提问于 2025-04-16 02:46

在这段代码中:

   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 个回答

0

编辑: 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')
4

你可以试试:

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

这可以帮助你调试编码问题。

5

我不太明白你想用 name.string.decode('utf-8') 做什么。正如BeautifulSoup的文档所说的那样,“BeautifulSoup给你的是Unicode,真是的”。所以 name.string 其实已经解码了——它是Unicode格式的。如果你想的话,可以把它编码回utf-8,但你不能再进一步解码了。

撰写回答