使用Python发送桌面通知时出现Unicode编码问题

Unicode-encode issues while sending desktop notification using Python

我正在从一个网站上获取最新的足球成绩,并在桌面(OSX)上发送通知。我正在用漂亮的汤刮数据。生成此错误的Unicode数据有问题

1
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 2: ordinal not in range(128).

所以我在开头插入了这个代码,解决了输出终端时的问题。

1
2
3
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

但当我在桌面上发送通知时,问题就存在了。我使用终端通知程序发送桌面通知。

1
2
3
4
5
def notify (title, subtitle, message):
    t = '-title {!r}'.format(title)
    s = '-subtitle {!r}'.format(subtitle)
    m = '-message {!r}'.format(message)
    os.system('terminal-notifier {}'.format(' '.join((m, t, s))))

下图描述了终端上的输出与桌面通知的对比。

终端输出。

enter image description here

桌面通知

Dektop Notification

另外,如果我试图替换字符串中的逗号,我会得到错误,

new_scorer = str(new_scorer[0].text).replace(",","")

1
2
3
File"live_football_bbc01.py", line 41, in get_score
    new_scorer = str(new_scorer[0].text).replace(",","")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 2: ordinal not in range(128)

如何在桌面通知上获取输出,如终端上的通知?谢谢!

编辑:桌面通知的快照。(解决)

enter image description here


您正在使用!r进行格式化,这将为您提供repr输出,忽略糟糕的重新加载逻辑,并在任何地方使用unicode:

1
2
3
4
5
def notify (title, subtitle, message):
    t = u'-title {}'.format(title)
    s = u'-subtitle {}'.format(subtitle)
    m = u'-message {}'.format(message)
    os.system(u'terminal-notifier {}'.format(u' '.join((m, t, s))))

或编码:

1
2
3
4
5
def notify (title, subtitle, message):
    t = '-title {}'.format(title.encode("utf-8"))
    s = '-subtitle {}'.format(subtitle.encode("utf-8"))
    m = '-message {}'.format(message.encode("utf-8"))
    os.system('terminal-notifier {}'.format(' '.join((m, t, s))))

当您调用str(new_scorer[0].text).replace(",,,,")时,您试图将其编码为ASCII,需要指定要使用的编码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
In [13]: s1=s2=s3= u'\xfc'

In [14]: str(s1) # tries to encode to ascii
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-14-589849bdf059> in <module>()
----> 1 str(s1)

UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 0: ordinal not in range(128)

In [15]:"{}".format(s1) +"{}".format(s2) +"{}".format(s3) # tries to encode to ascii---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-15-7ca3746f9fba> in <module>()
----> 1"{}".format(s1) +"{}".format(s2) +"{}".format(s3)

UnicodeEncodeError: '
ascii' codec can't encode character u'\xfc' in position 0: ordinal not in range(128)

您可以直接编码:

1
2
In [16]:"{}".format(s1.encode("utf-8")) +"{}".format(s2.encode("utf-8")) +"{}".format(s3.encode("utf-8"))
Out[16]: '\xc3\xbc\xc3\xbc\xc3\xbc'

或者使用所有Unicode,在格式字符串前加上u,最后编码:

1
2
3
4
5
6
In [17]: out = u"{}".format(s1) + u"{}".format(s2) + u"{}".format(s3)
In [18]: out
Out[18]: u'\xfc\xfc\xfc'

In [19]: out.encode("utf-8")
Out[19]: '\xc3\xbc\xc3\xbc\xc3\xbc'

如果您使用!r,那么您将始终转到输出中的字节:

1
2
3
4
5
In [30]: print"{}".format(s1.encode("utf-8"))
ü

In [31]: print"{!r}".format(s1).encode("utf-8")
u'\xfc'

还可以使用子进程传递参数:

1
2
3
4
5
6
7
from subprocess import check_call


def notify (title, subtitle, message):
    cheek_call(['terminal-notifier','-title',title.encode("utf-8"),
                '-subtitle',subtitle.encode("utf-8"),
                '-message'.message.encode("utf-8")])


使用:_sys.getfilesystemcodeding`获取编码

用它编码字符串,忽略或替换错误:

1
2
3
4
5
import sys

encoding = sys.getfilesystemencoding()
msg = new_scorer[0].text.replace(",","")
print(msg.encode(encoding, errons="replace"))