概要
開発していてあるわけではなく、営業の先輩から「過去のメールのやりとりをExcel一覧で見れるようにしておきたい」という相談をもらい、「地味にeml形式だからテキストに起こすの面倒ですからね…」という共感の元、やってみたという話です。
やったこと
- ディレクトリに保存してある「emlファイルの一覧」から、「差出人」「宛先」「件名」「本文」「作成日時」が項目となっているCSVファイルを作った。
- 言語はpythonです。こういう痒いのをやりやすい。
- jupyter notebookでやりました。便利。
処理手順
必要パッケージのインポート
- 主にメールの処理に必要なもの
- CSV処理に必要なもの
- 日付処理に必要なもの
import email
import os
from email import policy
from email.parser import BytesParser
import csv
from datetime import datetime
(関数定義)emlファイルをメールオブジェクトに
def parse_eml(file_path):
with open(file_path, 'rb') as f:
msg = BytesParser(policy=policy.default).parse(f)
return msg
(関数定義)メールオブジェクトからテキスト情報を取得
def get_email_text(email_msg):
text = ""
if email_msg.is_multipart():
for part in email_msg.walk():
if part.get_content_type() == 'text/plain':
charset = part.get_content_charset() or 'utf-8'
text = part.get_payload(decode=True).decode(charset, errors='replace')
break
else:
if email_msg.get_content_type() == 'text/plain':
charset = email_msg.get_content_charset() or 'utf-8'
text = email_msg.get_payload(decode=True).decode(charset, errors='replace')
return text
(関数定義)各メール情報を取得
def get_email_data(email_msg):
from_address = email_msg.get('From', '')
to_addresses = email_msg.get('To', '')
to_addresses = '/'.join([addr.strip() for addr in to_addresses.split(',')]) # 複数の宛先を '/' 区切りにします
subject = email_msg.get('Subject', '')
text = get_email_text(email_msg)
sent_date = email_msg.get('Date', '')
return {
'from': from_address,
'to': to_addresses,
'subject': subject,
'text': text,
'date': sent_date,
}
(関数定義)取得したテキスト情報をCSVファイルに書き出し
def write_to_csv(file_name, data):
with open(file_name, 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['from', 'to', 'subject', 'text', 'date']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for item in data:
writer.writerow(item)
実行処理
- emlファイルの一覧は、同階層の「mail」ディレクトリに入れました
if __name__ == '__main__':
eml_dir = './mail' # emlファイルが保存されているディレクトリ
timestamp = datetime.now().strftime('%Y%m%d%H%M%S') # 処理開始時刻を取得
output_csv = f'output_{timestamp}.csv' # 出力するCSVファイル名に時刻を追加
email_data = []
for filename in os.listdir(eml_dir):
if filename.endswith('.eml'):
file_path = os.path.join(eml_dir, filename)
email_msg = parse_eml(file_path)
email_info = get_email_data(email_msg)
email_data.append(email_info)
write_to_csv(output_csv, email_data)
おわり
- 言語や環境は色々ありますが「これ手動でやったら5時間ぐらいかかりそうだな」みたいなものを1時間で終わらせるにはpythonあたりがラクに着手できてよいですね。