【问题标题】:email.header not handling Finnish characters?email.header 不处理芬兰语字符?
【发布时间】:2015-06-17 13:23:52
【问题描述】:

某个 Python API 为结束词 Järvenpää 返回 u'J\xe4rvenp\xe4\xe4'

其中 \xe4 == ä

然后我调用 email.header 将此字段添加到要打印的标题中。

email.header 在尝试解码元音变音时跌倒:

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/email/header.py", line 73, in decode_header
    header = str(header)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 1: ordinal not in range(128)

我已经尝试了几件事:

  • 添加# -*- coding: utf-8 -*- 到 header.py 的顶部
  • 在将芬兰语字符串传递给 email.header 之前调用 unicode()
  • 在将芬兰语字符串传递给 email.header 之前调用 .encode('utf-8')

没有人能解决问题。我做错了什么?我想一个解决方案不会涉及修改 header.py(一个核心 Python 模块)。

Python 版本:2.7.10

更新:

Header() 没有被直接实例化。相反,我在字符串上调用 decode_header() 函数:

email.Header.decode_header(theString)

现在看来,只是这样扩展:

email.Header.decode_header(theString.encode('utf-8'))

解决问题

【问题讨论】:

  • 您是如何使用email 模块添加标题的?请在问题中包含您的代码,最好是MCVE
  • @LukasGraf 查看我的更新。你会相信这个解决方案是可靠的吗?或者你会建议一些不同的东西吗?
  • 等待 - 您是在尝试创建一个标头(发送电子邮件)还是解析一个标头(阅读电子邮件)?
  • decode_header 是一个帮助函数,用于通过将RFC 2047 电子邮件标头 解码为(decoded_string, charset) 元组列表将其转换为Python 字符串。您能否用一个完整的示例来更新您的问题,以说明您正在尝试做什么(不仅仅是 sn-ps)?
  • @LukasGraf 这里有更清晰、更全面的问题描述:stackoverflow.com/questions/30907708/…

标签: python unicode utf-8 utf python-unicode


【解决方案1】:

为了让email.header 模块为您处理编码并创建正确的标头,您必须使用您的字符串和应该编码的字符集创建email.header.Header 的实例:

>>> h = Header(text, charset)

例如:

>>> t = u'J\xe4rvenp\xe4\xe4'
>>> print t
Järvenpää
>>> from email.header import Header
>>> h = Header(t, 'utf-8')
>>> h
<email.header.Header instance at 0x7fc2636e7950>
>>> print h
=?utf-8?b?SsOkcnZlbnDDpMOk?=
>>> h = Header(t, 'iso-8859-1')
>>> print h
=?iso-8859-1?q?J=E4rvenp=E4=E4?=

字符串可以是 unicode 字符串或 字节字符串

  • 如果您使用 unicode 字符串,charset 只会影响标头的编码方式编码
  • 如果您使用字节字符串,charset 将确定假定字节字符串采用什么编码,以及将使用什么编码对标头进行编码。如果您提供的字节字符串无法使用该charset 解码,则会引发异常。

【讨论】:

    【解决方案2】:

    AFAIK,str() 处理 ascii,这就是你得到错误的原因。如果你的字符串是 unicode 你应该做header = unicode(header),如果不是它应该首先被解码。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    header = unicode("Järvenpää".decode('UTF-8'))
    print header
    

    输出

    Järvenpää
    

    【讨论】:

    • "bytestring".decode(charset) 将已经返回一个 unicode 实例 - 额外的 unicode() 调用根本没有任何作用。如果是这样(例如,当您执行 unicode(bytestring) 时),它将始终尝试使用系统默认编码(在 Python 2.x 中为 ascii)隐式解码 bytestring - 所以它会因任何不正确的编码而失败不是ASCII。所以请不要使用unicode(bytestring)
    • 如您所愿。芬兰语的正常编码是 ISO-8859-15。这就是为什么我举了一个例子。我在终端中尝试了该字符串。
    • 没有“芬兰语的正常编码”之类的东西 - 如果您正在处理字节字符串,您总是必须知道使用的编码。您的答案的问题在于您完全忽略了问题是关于电子邮件标题的事实,并且您陈述的事情完全是错误的。
    • 是的,没错。你的答案的问题是你忽略了“header = str(header)”的OP代码
    • 好的,好的。你是最聪明的。反正我给你减分了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 2013-10-10
    相关资源
    最近更新 更多