メモの日々


2017年05月19日(金) [長年日記]

[python] Pythonでメールのヘッダフィールドをエンコードする

メールのヘッダフィールドに日本語を含めるにはRFC 2047に従ってエンコードする必要があるようである。Pythonではこのエンコード処理をemail.headerモジュールで行うことができる。

% python
Python 2.7.5 (default, Nov  6 2016, 00:28:07)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import email.header
>>> print email.header.Header(u"あ" * 100, "iso-2022-jp", header_name="Subject")
=?iso-2022-jp?b?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?=
 =?iso-2022-jp?b?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?=
 =?iso-2022-jp?b?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?=
 =?iso-2022-jp?b?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?=
 =?iso-2022-jp?b?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?=
 =?iso-2022-jp?b?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIkIiQiJCIbKEI=?=

このように、Headerオブジェクトを生成すればエンコードができる。header_nameは指定しなくても問題ないが、指定するとエンコード後の最初の行の文字数をヘッダ名の分(上の例だと「Subject:」)だけ減らしてくれる。

上の例ではcharsetとして"iso-2022-jp"を指定しているが、この場合もしエンコード対象文字列にiso-2022-jpでエンコードできない文字が含まれていると自動的にutf-8でエンコードしてくれて気が利いている。

>>> print email.header.Header(u"①" * 100, "iso-2022-jp", header_name="Subject")
=?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=
 =?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=
 =?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=
 =?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=
 =?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=
 =?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=
 =?utf-8?b?4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg4pGg?=