【问题标题】:Unicode-encode issues while sending desktop notification using Python使用 Python 发送桌面通知时出现 Unicode 编码问题
【发布时间】:2017-01-12 18:32:04
【问题描述】:

我正在从网站获取最新的足球比分并在桌面 (OS X) 上发送通知。我正在使用 BeautifulSoup 来抓取数据。我遇到了导致此错误的 unicode 数据问题

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

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

import sys 
reload(sys)
sys.setdefaultencoding('utf-8') 

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

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))))

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

终端输出。

桌面通知

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

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

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)

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

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

【问题讨论】:

  • 不要调用str,根据需要进行编码/解码。你为什么打电话给 str 呢?此外,您的重新加载逻辑是一个糟糕的主意。 stackoverflow.com/questions/3828723/…。为什么应该删除像stackoverflow.com/a/31137935/2141635 这样的答案的另一个例子
  • 然后我在终端上得到正确的输出,但在桌面通知上,字符串中带有 'u',如` 'ukrkic' 和 'uAg\xc3\b...`
  • 你使用的是python 2吗?如果您需要并且不需要,这是 Python 3 的默认行为更方便的一个空间。
  • 哦,是吗?我正在使用 Python 2.7。会调查的。也许是时候切换到 Python 3 了。

标签: python unicode utf-8 ascii


【解决方案1】:

您正在使用 !r 进行格式化,它会为您提供 repr 输出,忘记可怕的重新加载逻辑并在任何地方使用 unicode:

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))))

或编码:

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,您需要指定要使用的编码:

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)

您可以立即编码:

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 并最后编码:

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,您总是会转到输出中的字节:

In [30]: print "{}".format(s1.encode("utf-8"))
ü

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

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

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")])

【讨论】:

  • 我正在使用 repr 来获取字符串的引号,以便它与终端通知器语法 terminal-notifier -[message|list|remove] [VALUE|ID|ID] [options] 匹配。否则我会得到错误,sh: -c: line 0: syntax error near unexpected token (' sh: -c: line 0: terminal-notifier -message Krkic (49' minutes pen) -title Stoke Vs Man City -subtitle 1-4 FT'
  • 使用编码版本,我在桌面通知器上仍然得到相同的输出。
  • 使用 subprocess 而不是 os.system 并将 args 的 lsit 传递给 subprocess.check_call
  • 除桌面通知外,一切正常。我怀疑终端通知器是否有内置的编码/解码问题。
  • 作为参考,我编辑了包含有效桌面通知的问题。
【解决方案2】:

使用:ˋsys.getfilesystemencoding` 获取您的编码

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

import sys

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

【讨论】:

    猜你喜欢
    • 2021-02-01
    • 2016-12-23
    • 2017-10-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    相关资源
    最近更新 更多