这是代码:
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数据?
答案 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') + '")'