ともだちはすくないです

30代既婚男子。子供2人。日経先物トレードとかプログラミングとか英語とか

pythonで表示した2軸チャート画像を添付ファイルにしてメール送信する。


前回の記事では2つの指標(記事内では米金利と日経)の比較チャートを作成しました。

trade-and-develop.hatenablog.com



そして思ったのです。これ、色んな指標を比較するから、その度にチャート画像を保存するのもめんどくさいし、通勤時間などの隙間時間にスマホでまとめて見たい、と。そう思った僕は昨日の夜も妻とお酒を飲みながら、PCに向かいひたすらに調べまくっていました。なかなか手間取りました、うまく自分のGmail宛てに、チャート画像を添付ファイルとして送信することが出来ましたのでメモしときます。




まず、チャート画像のメール送信とは以下のステップで実現できそうです。


1,チャートを作成する。

2、チャートをPC上に保存する。

3、PC上に保存したファイルを添付してGmail送信する。




1の「チャートを作成する。」は前回の記事で行なったので、今回は2と3をメモします。




2、チャートをPC上に保存する。

これは簡単です。チャートを作成(プロット)した後で以下のコードを追加すればOK。これでターミナルで作業しているフォルダに画像が保存されます。念のためですが以下の「sample.png」は保存されるファイル名です。そのため任意で良いです。

plt.savefig("sample.png")


3、PC上に保存したファイルを添付してGmail送信する。

さて、ついに保存したファイルを添付ファイルとしてGmail送信するところです。まずはチャート画像を保存した後に以下のコードを挿入します。ここから「sendGmailAttach」というモジュールを呼び出すことでメールを送信します。

if __name__ == '__main__':
    to = 'xxxxxxx@gmail.com'  # メール送信先
    sub = 'xxxxxxx' #メールタイトル
    body = ''  # メール本文(今回は画像送信のため、本文なし)

     # nameは送信されたときの添付ファイル名。pathは添付するファイルが現在格納されているパス。(ファイル名も必要)
    attach_file = {'name': 'sample.png', 'path': '/Users/user_name/Desktop/trade/sample.png'} 
    sendGmailAttach(to, sub, body, attach_file)




さて、次にメールを実際に送るプログラムです。

from email.mime.text import MIMEText
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart


class sendGmailAttach:
    username, password = 'xxxxxxx@gmail.com', 'xxxxxxxx'

    def __init__(self, to, sub, body, attach_file):
        host, port = 'smtp.gmail.com', 465
        msg = MIMEMultipart()
        msg['Subject'] = sub
        msg['From'] = self.username
        msg['To'] = to

        # メール本文
        body = MIMEText(body)
        msg.attach(body)

        # 添付ファイルの設定
        attachment = MIMEBase('image', 'png')
        file = open(attach_file['path'], 'rb+')
        attachment.set_payload(file.read())
        file.close()
        encoders.encode_base64(attachment)
        attachment.add_header("Content-Disposition", "attachment", filename=attach_file['name'])
        msg.attach(attachment)

        smtp = smtplib.SMTP_SSL(host, port)
        smtp.ehlo()
        smtp.login(self.username, self.password)
        smtp.mail(self.username)
        smtp.rcpt(to)
        smtp.data(msg.as_string())
        smtp.quit()



ハマった点は以下。

 msg = MIMEMultipart()

これをやってないと以下のエラーで怒られます。

email.errors.MultipartConversionError: Cannot attach additional subparts to non-multipart/*



もうひとつ

encoders.encode_base64(attachment)

これをやってないと以下のエラーで怒られます。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte




ということでプログラムを動かすと無事にチャートが添付ファイルとしてメール送信されておりました。いや、こんな簡単なコード書くのに数時間かかったぜ。。日本語での正確な情報少なかったので誰かの助けになれば!!!以下がGmailから添付ファイルを開いたときのスクショです。

f:id:trade-and-develop:20170312145758p:plain