我正在编写一个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 格式文档。在使用 IDLE GUI for Windows 时似乎没有问题,但是当我改用 Windows 控制台时出现了问题。返回的页面有一个 U+2014 字符(em-dash),print 函数可以在 Windows GUI(可能是 Code Page 1252)中正确地转换,但在 Windows 控制台(Code Page 850)中无法转换。由于 strict
是默认行为,因此会收到以下错误:
UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 10248: character maps to <undefined>
我可以用这段相当丑陋的代码来解决它:
print(data.decode('utf-8').encode('cp850','replace').decode('cp850'))
现在它用一个
?
替换了有问题的字符“—”。虽然不是理想情况(连字符应该是更好的替代品),但已经足够满足我的目的。我对我的解决方案有几个不喜欢的地方:
1. 代码很丑,需要进行解码、编码和再次解码。 2. 它只能解决这种情况的问题。如果我将程序移植到使用其他编码(Latin-1、CP437、回到CP1252等)的系统上,它应该能识别目标编码,但实际上它并不能。(例如,当再次使用IDLE GUI时,破折号也会丢失,而以前则没有发生过) 3. 如果破折号被翻译为连字符而不是问号,那就更好了。
问题不在于破折号(我可以想出几种解决这个问题的方法),而是我需要编写健壮的代码。我正在从数据库中提取数据填充页面,而这些数据可能会出现问题。我可以预见到许多其他冲突情况:'Á' U+00c1(在我的数据库中可能存在)可以转换为CP-850(适用于西欧语言的DOS/Windows控制台编码),但不能转换为CP-437(适用于美国英语的编码,在许多Windows安装中是默认的)。
所以,问题是:
是否有更好的解决方案可以使我的代码不依赖于输出接口编码?