質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

469閲覧

Macで複雑なメール検索をしたい

kg7652

総合スコア14

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/12/31 11:04

編集2019/01/02 14:22

Mac(macOS 10.14.2)の標準メーラーを使用していますが、おそらくメールの検索に正規表現が使えません。
(調べた限りでは情報が見つかりません)

Macで正規表現が使えるメール ソフトはありますでしょうか?
あるいは、PHPやPythonなどのスクリプト言語から標準メーラーのメールボックスを検索することができますでしょうか?
具体的な方法または関連情報などお教えいただけましたら幸いです。

【追記】
一度、mail.appの「メールボックスを書き出す」で書き出した上で、
http://techu1999.sakura.ne.jp/python/category/%E3%83%A1%E3%83%BC%E3%83%AB%E5%87%A6%E7%90%86/
こちらのブログの「Thunderbirdに届いたメールを処理する」という記事中のサンプルソースをデータファイルのパス以外はそのまま試し、
・メールアドレス+日時
・サブジェクト
・本文
のセットが次々と出力されるテストをしました。(結果はテキストファイルへリダイレクト)

今回書き出したmboxファイルは2.15GBで、
途中まで(7件)うまく書き出されましたが8件目のメールアドレス+日時の行が出力されたところで止まってしまいました。
そこまで数十秒待たされる感じです。

仮にうまくいっても待ち時間が長いので現状のメールボックスの状態では使いにくいと感じました。

でも、そのあたりがクリアできれば、正規表現での検索も一応は実現できそうです。

なにか問題(途中で終わってしまう。あるいは処理に時間がかかる)の解決につながる情報がございましたらお教えいただけましたら幸いです。

以下、上記ブログに掲載されていたソース(パスの部分のみ改変あり)です

python

1import mailbox 2from email.header import decode_header 3 4mail_box = mailbox.mbox("/pathTo/mbox") 5for key in mail_box.keys(): 6 a_msg = mail_box.get(key) 7 from_str = a_msg.get_from() 8 print(from_str) 9 10 usbj = '' 11 for bstr,enc in decode_header(a_msg['Subject']) : 12 if enc == None: 13 usbj += bstr.decode("ascii", "ignore") 14 else: 15 usbj += bstr.decode(enc, "ignore") 16 print("subject: "+usbj) 17 18 for aa_msg in a_msg.walk(): 19 if not 'text' in aa_msg.get_content_type(): 20 continue #"text"パートでなかったら次のパートへ 21 if aa_msg.get_content_charset() : 22 a_text = aa_msg.get_payload(decode=True).decode(aa_msg.get_content_charset(), "ignore") 23 else: 24 if "charset=shift_jis" in str(aa_msg.get_payload(decode=True)): 25 #ひとまず シフトJISだけ特別対応。 26 a_text = aa_msg.get_payload(decode=True).decode("cp932", "ignore") 27 else: 28 print ("** Cannot decode.Cannot specify charset ***"+msg.get("From")) 29 print(a_text) 30 continue 31

【追記】
別のメールボックス(12MB)で試したところ、全384件が出力され、待ち時間もほぼ感じない程度でした。

【追記】
その後、止まった時のエラーメッセージをよく見てソースをいじったところ、スクリプト自体は正常終了するようになりました。

python

1import mailbox 2from email.header import decode_header 3import re 4 5mail_box = mailbox.mbox("/pathTo/mbox") 6for key in mail_box.keys(): 7 try: 8 a_msg = mail_box.get(key) 9 except: 10 pass 11 12 from_str = a_msg.get_from() 13 print(from_str) 14 15 usbj = '' 16 for bstr,enc in decode_header(str(a_msg['Subject'])) : 17 if enc == None: 18 pass 19 else: 20 usbj += bstr.decode(enc, "ignore") 21 print("subject: "+usbj) 22 23 for aa_msg in a_msg.walk(): 24 if not 'text' in aa_msg.get_content_type(): 25 continue #"text"パートでなかったら次のパートへ 26 if aa_msg.get_content_charset() : 27 a_text = aa_msg.get_payload(decode=True).decode(aa_msg.get_content_charset(), "ignore") 28 else: 29 if "charset=shift_jis" in str(aa_msg.get_payload(decode=True)): 30 #ひとまず シフトJISだけ特別対応。 31 a_text = aa_msg.get_payload(decode=True).decode("cp932", "ignore") 32 else: 33 print ("** Cannot decode.Cannot specify charset ***"+str(aa_msg.get("From"))) 34 a_text = re.sub(r'<(?:!|HTML|html).*>', '' , a_text, flags=re.DOTALL) 35 print(a_text) 36 continue

と変更してエラーを無視するようにしました。

結果、全15800件くらいのメールのうち、14500件ほどが出力されます。

1300件ほどが出力されていませんが、エラーの理由はよくわかっていません。

最初に出ていたエラーメッセージを根拠に
元のソースの13行目を修正したあと、以下のようなことなるエラーメッセージでました。

Traceback (most recent call last):
File "mailSearch.py", line 6, in <module>
a_msg = mail_box.get(key)
File "/usr/local/Cellar/python/3.7.2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/mailbox.py", line 66, in get
return self.getitem(key)
File "/usr/local/Cellar/python/3.7.2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/mailbox.py", line 73, in getitem
return self.get_message(key)
File "/usr/local/Cellar/python/3.7.2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/mailbox.py", line 781, in get_message
msg.set_from(from_line[5:].decode('ascii'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)

これは、ライブラリが関わっていたので、元のソースの6行目を変更してエラーを無視すうるようにした流れです。

出力されないメールの共通点はよくわからず、同じ相手からの似たようなメールでも出力されているものとされないものがあったりします。

修正後のコードで正規表現を使っていますが、これはHTMLメールを削除するためで、本当はHTMLメールを適切にテキスト化したいのですが、方法がわからず、その段階に至っていません。

今後、
・HTMLメールのテキスト化のやり方
・エラーの原因と対応法
が解決したら、当初の目的の正規表現を用いた検索もできそうだと思っています。
mboxのファイルサイズが大きいのでかなり待たされますが、それでも人力で検索することが困難であれば、数分待つだけで結果が得られればありがたいです。

ただ、あらかじめmboxを書き出さずに直接mail.appのメールボックスをpythonからアクセスできるのいいのですが方法がわかりません。

3つの課題について引き続き何か情報をいただけましたら幸いです。

【追記】
2つ目のソースで正規表現を利用してHTMLメールを削除していますが、これをやりたかったわけではなく、出力されるファイルにHTMLメールが含まれると、ざっと出力ファイル内を目視するときにじゃまだったから削除している状況です。最終的にはHTMLソースの状態でも検索はできると考えています。

基本的に、
・Macで正規表現(後読み、先読みが使えるのがよい)を検索に使えるメーラーがあるか
・でなければ、直接mail.appのデーターにスクリプト言語からアクセスできないか
というのが質問の内容です。
最初に質問した後に発見したブログに掲載されていたpythonコードで、mboxファイルを扱えそうだったので試しましたが、数件だけ出力されて止まってしまったため、とりあえず正常終了するように手直ししたところまでを追記しました。この質問には回答は付いていないもののそこそこ閲覧数があったので、興味を持たれる方もいのだと思い、自分なりの試行錯誤を追記しています。どなたかが試していただければ情報を得られるかもしれないと期待しております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/12/31 11:10

正規表現で検索しないといけないほど雑多なメールが届いてるわけじゃあるまいし
kg7652

2018/12/31 15:46

わけじゃあるまいし
退会済みユーザー

退会済みユーザー

2019/01/02 13:39

当初の目的だと思われるHTMLメールを検索したいって解決してるなら解決済みにするか 別の問題にするなら件名を変更したら?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問