将python脚本输出输出到文件时出现Unicode错误

时间:2012-04-04 19:51:49

标签: python unicode beautifulsoup

这是代码:

print '"' + title.decode('utf-8', errors='ignore') + '",' \
      ' "' + title.decode('utf-8', errors='ignore') + '", ' \
      '"' + desc.decode('utf-8', errors='ignore') + '")'

title和desc由Beautiful Soup 3( p [0] .text p [0] .prettify )返回,据我所知BeautifulSoup3文档采用UTF-8编码。

如果我跑

python.exe script.py > out.txt

我收到以下错误:

Traceback (most recent call last):
  File "script.py", line 70, in <module>
    '"' + desc.decode('utf-8', errors='ignore') + '")'
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 264
: ordinal not in range(128)

但是如果我跑

python.exe script.py

我没有错误。仅在指定输出文件时才会发生。

如何在输出文件中获得良好的UTF-8数据?

4 个答案:

答案 0 :(得分:12)

您可以使用编解码器模块将unicode数据写入文件

import codecs
file = codecs.open("out.txt", "w", "utf-8")
file.write(something)

'print'输出到标准输出,如果你的控制台不支持utf-8,即使你将stdout传输到文件也会导致这样的错误。

答案 1 :(得分:7)

这种情况下的Windows行为有点复杂。您应该听取其他建议,并在输入过程中内部使用unicode进行字符串和解码。

对于你的问题,你需要打印编码的字符串(只有你知道哪个编码!)在stdout重定向的情况下,但你必须打印unicode字符串,以便简单的屏幕输出(和python或Windows控制台处理转换为正确编码)。

我建议以这种方式构建脚本:

# -*- coding: utf-8 -*- 
import sys, codecs
# set up output encoding
if not sys.stdout.isatty():
    # here you can set encoding for your 'out.txt' file
    sys.stdout = codecs.getwriter('utf8')(sys.stdout)

# next, you will print all strings in unicode
print u"Unicode string ěščřžý"

更新:另请参阅其他类似问题:Setting the correct encoding when piping stdout in Python

答案 2 :(得分:1)

将文本转换为unicode以便打印它是没有意义的。使用unicode处理数据,将其转换为某种编码输出。

你的代码改为:你在python 2上,所以你的默认字符串类型(str)是一个字节串。在你的语句中,你从一些utf编码的字节串开始,将它们转换为unicode,用引号括起来(常规str被强制为unicode以便组合成一个字符串)。然后,将此unicode字符串传递给print,将其推送到sys.stdout。为此,需要将其转换为字节。如果您正在写入Windows控制台,它可以以某种方式进行协商,但如果您重定向到常规的哑文件,它会回到ascii并抱怨,因为没有无损失的方法。

解决方案:不要给print一个unicode字符串。 “编码”你自己选择的代表:

print "Latin-1:", "unicode über alles!".decode('utf-8').encode('latin-1')
print "Utf-8:", "unicode über alles!".decode('utf-8').encode('utf-8')
print "Windows:", "unicode über alles!".decode('utf-8').encode('cp1252')

重定向时,所有这一切都应该没有投诉。它可能在您的屏幕上看起来不正确,但是用记事本或其他东西打开输出文件,看看您的编辑器是否设置为查看格式。 (Utf-8是唯一有希望被检测到的人.cp1252可能是Windows的默认设置。)

一旦解决了这个问题,请清理代码并避免使用print进行文件输出。使用codecs模块,打开codecs.open而不是普通打开的文件。

PS。如果您正在解码utf-8字符串,转换为unicode应该是无损的:您不需要errors=ignore标志。当您转换为ascii或Latin-2或其他任何内容时,这是合适的,并且您只想删除目标代码页中不存在的字符。

答案 3 :(得分:0)

问题: 如果您在Windows上运行:

python.exe script.py

以下内容将生效:

sys.stdout.encoding: utf-8
sys.stdout.isatty(): True

但是,如果您运行:

python.exe script.py > out.txt

您将有效地拥有这个:

sys.stdout.encoding: cp1252
sys.stdout.isatty(): False

因此,可能的解决方案(在PYTHON中为3.7):

import sys
if not sys.stdout.isatty():
    sys.stdout.reconfigure(encoding='utf-8')

print '"' + title.decode('utf-8', errors='ignore') + '",' \
      ' "' + title.decode('utf-8', errors='ignore') + '", ' \
      '"' + desc.decode('utf-8', errors='ignore') + '")'

另请参阅: How to set sys.stdout encoding in Python 3?