此间少年 发表于 2018-9-20 15:52:51

UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in positi...

我正在编写一个Python(Python 3.3)程序,使用POST方法将一些数据发送到网页。主要用于调试过程我得到页面结果并使用print()函数在屏幕上显示它。
代码是这样的:
conn.request("POST", resource, params, headers)
response = conn.getresponse()
print(response.status, response.reason)
data = response.read()
print(data.decode('utf-8'));
该HTTPResponse .read()方法返回一个bytes编码页面的元素(这是一个格式良好的UTF-8文档)在我停止使用Windows的IDLE GUI并使用Windows控制台之前,这似乎没问题。返回的页面有一个U + 2014字符(em-dash),打印功能在Windows GUI中很好地转换,但在Windows控制台中没有。鉴于strict默认行为,我收到以下错误:
UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 10248: character maps to <undefined>

蛋蛋超人 发表于 2018-9-20 15:54:49

我看到三个解决方案:
1.        更改输出编码,因此它将始终输出UTF-8。请参阅例如在Python中管道stdout时设置正确的编码,但我无法让这些示例工作。
2.        以下示例代码使输出可以识别你的目标字符集。
3.        # -*- coding: utf-8 -*-
4.        import sys
5.       
6.        print sys.stdout.encoding
7.        print u"Stöcker".encode(sys.stdout.encoding, errors='replace')
print u"Стоескер".encode(sys.stdout.encoding, errors='replace')
此示例使用问号正确替换了我名称中的任何不可打印字符。
如果你创建一个自定义打印功能,例如调用myprint,使用该机制正确编码输出,你可以简单地用myprint必要的替换打印,而不会使整个代码看起来很丑。
8.        在软件开头全局重置输出编码:
页面http://www.macfreek.nl/memory/Encoding_of_Python_stdout有一个很好的总结如何更改输出编码。特别是“Stdout周围的StreamWriter Wrapper”部分很有意思。基本上它说改变I / O编码函数如下:
在Python 2中:
if sys.stdout.encoding != 'cp850':
sys.stdout = codecs.getwriter('cp850')(sys.stdout, 'strict')
if sys.stderr.encoding != 'cp850':
sys.stderr = codecs.getwriter('cp850')(sys.stderr, 'strict')
在Python 3中:
if sys.stdout.encoding != 'cp850':
sys.stdout = codecs.getwriter('cp850')(sys.stdout.buffer, 'strict')
if sys.stderr.encoding != 'cp850':
sys.stderr = codecs.getwriter('cp850')(sys.stderr.buffer, 'strict')
如果在CGI输出HTML中使用,你可以将'strict'替换为'xmlcharrefreplace',以获取不可打印字符的HTML编码标记。
随意修改方法,设置不同的编码,....注意它仍然无法输出非指定的数据。因此,任何数据,输入,文本都必须正确转换为unicode:

# -*- coding: utf-8 -*-
import sys
import codecs
sys.stdout = codecs.getwriter("iso-8859-1")(sys.stdout, 'xmlcharrefreplace')
print u"Stöcker"                # works
print "Stöcker".decode("utf-8") # works
print "Stöcker"               # fails

污妖王 发表于 2018-9-20 15:55:44

def uprint(*objects, sep=' ', end='\n', file=sys.stdout):
    enc = file.encoding
    if enc == 'UTF-8':
      print(*objects, sep=sep, end=end, file=file)
    else:
      f = lambda obj: str(obj).encode(enc, errors='backslashreplace').decode(enc)
      print(*map(f, objects), sep=sep, end=end, file=file)

uprint('foo')
uprint(u'Antonín Dvořák')
uprint('foo', 'bar', u'Antonín Dvořák')

强人锁男 发表于 2018-9-20 15:56:31

出于调试目的,你可以使用print(repr(data))。
要显示文本,请始终打印Unicode。不要硬编码环境的字符编码,例如cp850脚本内部。要解码http respone,请参阅在Python中获取HTTP响应的charset /编码的好方法。
要将Unicode打印到Windows控制台,你可以使用win-unicode-console包。
页: [1]
查看完整版本: UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in positi...