LoginSignup
0
0

More than 5 years have passed since last update.

Pythonのemailライブラリで差出人名がたまにデコードされない時の対処

Last updated at Posted at 2015-11-29

※注意
- 最新版のPythonだと解消されているようですので3.4以前をご利用のかた向けです。
- 以前の記事の補足です。
- 取得、エンコードをしているソースコードは以前の記事をどうぞ

現象

Pythonの標準ライブラリ"email"を使って日本語が含まれているメールの差出人名(From)を取得した際に、「たまにだけ」デコードできない状態で取得される。

例:
”日本語名 <xxxx@test.com>” という差出人名の場合

正常の場合 データ 文字コード
名前部分 ?ISO-2022-JP?B?Re5LEJeS……QKI=?= iso-2022-jp
アドレス部分 <xxxx@test.com> -
たまにエラー データ 文字コード
名前部分 ?ISO-2022……QK<txxxx@test.com>I=?= -

正常の場合は名前部分を文字コードにしたがってエンコードすれば日本語名を取得できます。
たまに起こるのが、エンコードされた文字列がそのままメールアドレスとひっついてbyte型(デコードできない)で取得されてしまう現象です。

原因と対処

メールのヘッダ部分(差出人や件名)の部分を判定して取得する機能はemailライブラリを構成するheader.pyにあります。
この中で差出人部分がエンコードされた文字であるかが判定され、データを分解して取得しています。
そこの判定部分がこちら

# Match encoded-word strings in the form =?charset?q?Hello_World?=
ecre = re.compile(r'''
  =\?                   # literal =?
  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset
  \?                    # literal ?
  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive
  \?                    # literal ?
  (?P<encoded>.*?)      # non-greedy up to the next ?= is the encoded string
  \?=                   # literal ?=
  (?=[ \t]|$)           # whitespace or the end of the string
  ''', re.VERBOSE | re.IGNORECASE | re.MULTILINE)

コメントの通り、=?charset?q?・・・?= の形になっているかを判定するための正規表現です。こうなっていたら何かしらエンコードされている文字列です。
上記の現象が起きる原因は文字の最後(?=[ \t]|$)を判定している部分でした。殆どの場合はこれでよいのですが、一番最後に改行コードが混ざるメールがたまにあり、その場合、エンコードされていると判定されませんでした。
なので、

  (?=[ \t\r\n]|$)           # whitespace or the end of the string

としておくと対処できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0