前回のDay2では、PythonからYahooメールへIMAP接続し、受信箱のメール一覧を取得するところまで成功した。
途中、
「ログイン情報は合ってるのに接続できない」
という問題にぶつかりつつも、原因はYahoo側の“海外アクセス遮断”設定だったというオチまで含めて、かなり“開発してる感”のある回だったと思う。
そして今回のDay3。
次はいよいよ本文解析…と言いたいところなのだが、その前に問題があった。
コンソール表示、見づらい。
件名や送信者を print() でズラーっと流しているだけなので、メールが増えてくると普通に管理しづらい。
しかも今後やりたい事は、
- HTMLメール解析
- 本文取得
- URL抽出
- 正規化処理
- 「楽 天 カ ー ド」対策
- スコア判定
など、“中身を見ながら調整する作業”が中心になる。
となると、先にGUIを作っておいた方が絶対楽だ。
という訳で今回は、Tkinterを使ってGUIを導入し、
- メール一覧表示
- ログ表示
- 本文表示
この辺まで実装してみることにした。
ついでに、メール界に潜む“文字コードの闇”とも早速遭遇することになる。
TkinterでGUI化することにした
Day2までは、受信したメール情報をコンソールに表示していた。
これはこれで、接続テストとしては十分だった。
実際、
- Yahooメールへ接続
- ログイン
- INBOXを選択
- 最新メールを取得
- 件名と送信者を表示
という目的は達成できていた。
ただ、この先の開発を考えると、コンソールだけでは厳しい。
特にメール本文を扱い始めると、表示される情報量が一気に増える。
本文、HTML、URL、エラー、ログ。
それらが全部コンソールに流れていくと、かなり見づらい。
そこで今回は、Tkinterを使って簡単なGUIを作ることにした。
最初に作った画面はかなりシンプルだ。
- メールアドレス入力欄
- パスワード入力欄
- 接続して受信ボタン
- 最新メール一覧
- 本文表示欄
- ログ欄
まずはこれで十分。
凝ったデザインよりも、今は開発しやすさ優先である。
メール一覧をGUIで見られるだけでも、コンソール表示よりかなり分かりやすくなった。
GUIでメール一覧を表示する
今回のGUIでは、まず最新メールを一覧表示できるようにした。
表示する内容はシンプルに、
- 件名
- 送信者
この2つだけ。
メールソフトとして見れば最低限だが、今回の目的は“詐欺メール対策ツールの開発”なので、最初はこれで十分だ。
重要なのは、メールを見ながら次の処理を考えられること。
例えば、一覧を見るだけでも、
「この件名、明らかに怪しいな」
とか、
「送信者名はそれっぽいけど、ドメインが胡散臭いな」
みたいな情報が見えてくる。
コンソールにズラーっと流れていた時より、かなり把握しやすい。
さらに今回は、本文表示のためにIMAP接続を維持するようにした。
Day2のコードでは、受信後にすぐログアウトしていた。
しかし、本文を後から表示するには、メールを選択したタイミングでもう一度サーバーから情報を取る必要がある。
そのため今回は、
- 接続する
- メール一覧を取得する
- 接続は維持する
- 選択したメールの本文を取得する
- アプリ終了時にログアウトする
という流れに変更した。
この辺りで、ただの接続テストから少しずつ“ツール”っぽくなってきた。
本文取得にも挑戦してみた
GUI化したついでに、今回は本文取得にも挑戦してみた。
一覧でメールを選択して、
「本文表示」
ボタンを押すと、そのメール本文が表示される仕組みである。
さらに、メールをダブルクリックしても本文を表示できるようにした。
この辺りは地味だが、実際に使うとなるとかなり便利だ。
ただ、メール本文の取得は思ったより単純ではない。
メールには、
- text/plain
- text/html
- multipart
- 添付ファイル
など、いろいろな形式が混ざっている。
なので今回は、
- text/plain があれば優先して表示
- なければ text/html を表示
- 添付ファイルは無視
というシンプルな処理にした。
まだHTMLタグの除去まではしていない。
つまり、HTMLメールの場合はタグ付きで表示されることもある。
ただ、今回の目的はあくまで、
「本文を取得できるか」
の確認だ。
その意味では、本文表示まで成功した時点でDay3としてはかなり進んだと思う。
早速“メール界の闇”に触れる
本文取得まで進めたことで、いよいよメール処理の面倒な部分が見えてきた。
まず出てきたのが、件名の表示問題である。
一部のメールで、件名が普通の日本語ではなく、
=?iso-2022-jp?B?...
のような形式で表示されてしまった。
これは文字化けというより、メールの件名がMIMEエンコードされた状態のまま残っているようなものだ。
普通のメールならある程度デコードできるのだが、迷惑メールや詐欺メールはヘッダの作りが雑なこともある。
その結果、こちらの処理でうまく日本語に戻せないケースが出てきた。
正直、今回の目的からすれば大きな問題ではない。
なぜなら、そういうメールはだいたい消したい側のメールだからだ。
ただ、
「メール処理って思ったより面倒なんだな」
というのは、この段階でかなり実感した。
さらに今後はHTMLメールも相手にすることになる。
詐欺メールの多くはHTML形式なので、本文を取っただけではタグだらけになる可能性が高い。
つまり、Day3の時点で早くも、
- MIMEヘッダ
- 文字コード
- HTMLメール
- multipart
という、メール処理の面倒な要素が顔を出してきた。
やはりメールは魔境である。
それでもGUI化はかなり正解だった
細かい問題は出てきたが、それでも今回GUI化したのは正解だったと思う。
コンソール表示のままだと、件名、送信者、本文、ログが全部同じ場所に流れていく。
それに対してGUIでは、
- メール一覧
- 本文表示欄
- ログ欄
を分けて確認できる。
これだけで、開発中の見通しがかなり良くなった。
特に今後やりたい正規化処理では、
「元の本文」
「正規化後の本文」
「検出されたキーワード」
を見比べる必要がある。
例えば、
楽 天 カ ー ド
を、
楽天カード
として認識できているか確認するには、GUI上で結果を見られた方が圧倒的に楽だ。
さらに、本文表示までできるようになったことで、次回以降の開発がかなり進めやすくなった。
ここからようやく、
“メールを読むツール”
から、
“迷惑メールを判定するツール”
へ進めそうである。
Day3時点でできたこと
Day3でできたことを整理すると、かなり進んだ。
まず、Tkinterを使ってGUIを導入した。
これにより、コンソールに流していたメール情報を、画面上で一覧表示できるようになった。
次に、IMAP接続を維持する形に変更した。
Day2ではメール一覧を取ったらログアウトしていたが、今回は本文取得のために接続を維持するようにした。
さらに、選択したメールの本文表示にも対応した。
本文表示ボタンを押すか、メール一覧をダブルクリックすると、本文表示欄に内容が出る。
ここまで来ると、単なる実験コードではなく、かなり“ツールの原型”になってきた。
もちろん、まだ課題はある。
- 件名の一部がMIMEエンコードされたまま表示される
- HTMLメールはタグ付きで表示される
- 本文の整形はまだしていない
- 怪しいメール判定もまだない
ただ、Day3の目的としては十分だ。
メール一覧を見られる。
本文も見られる。
ログも確認できる。
これで、次の開発に進む土台は整った。
次回やること
Day3では、GUI化と本文取得まで到達できた。
次にやるべきことは、いよいよ本文の整形である。
現時点では、本文をそのまま表示しているだけなので、HTMLメールの場合はタグが混ざる。
これだと人間が読むにも微妙だし、プログラムで判定するにも扱いづらい。
なので次回は、
- HTMLタグの除去
- 本文の改行整理
- 全角半角の正規化
- 空白除去
- URL抽出
この辺りに進みたい。
特に重要なのが、Day1からずっと言っている、
楽 天 カ ー ド
みたいな表記ゆれ対策だ。
この手のフィルタ回避表現を、
楽天カード
として認識できるようにしないと、迷惑メール判定には使いづらい。
つまり次回は、
“本文を表示するツール”
から、
“本文を解析するツール”
へ進む回になる。
ここまで来れば、いよいよ詐欺メール判定の土台ができてくるはずだ。