Pythonを使って電子メールを送信する方法について見ていきます。
ここでは電子メールをGoogleのGmailを使って、メールを送信するコードを書いて行きます。
他のフリーメール(hotmailなど)やメールサーバーなどでも同様のことができるはずです。
PythonコードでGmailを送信する
では、Gmailを送信するコードをPythonで書いていきましょう。
送信元となるGmailのアカウント(メールアドレス)とパスワード、送信先のメールアドレスを用意しておきます。
また、gmailのホスト情報などが必要なので調べておきます。次のサイトに掲載されています。
これらを使って以下のようにコードを書いて行きます。
from email import message
import smtplib
smtp_host = 'smtp.gmail.com' # メールを送るSMTPサーバー
smtp_port = 587 # ポート番号
from_email = 'fromXXXemail@gmail.com' # 送信元のメールアドレス(Gmeilアドレス)
to_email = 'toXXXemail@gmail.com' # 送信先のメールアドレス
username = 'fromXXXemail@gmail.com' # ユーザーネームはGoogleアカウント(Gmailアドレス)
password = 'googlepassword' # Googleアカウントのパスワード
# 送信メールを作成する
msg = message.EmailMessage() # メッセージオブジェクトを作成
msg.set_content('これはPythonコードを使ったテストメールの本文です。') # メール本文
msg['Subject'] = 'test mail from python' # メールのタイトル(件名)
msg['From'] = from_email # メール送信元
msg['To'] = to_email # メール送信先
# メールサーバーへアクセスする
server = smtplib.SMTP(smtp_host, smtp_port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(username, password)
server.send_message(msg)
server.quit()
まず、メールを送信するのでメッセージとSMTPのライブラリをインポートします。
ホスト名とポート名を指定しますが、これはGmail の上の情報記事の中にあるものを記入します。そして、送信元のメールアドレス、送信先のメールアドレス、サーバーにログインするためのユーザーネームとパスワードを、それぞれの変数に代入しておきます。(記載のものは架空のものですので、各自の状況に合わせて書き換えてください)
メールを作成して行きます。message.EmailMessage()を使ってメールのオブジェクトを作ります。set_content()を使ってメール本文を記入し、Subjectにメールの件名、From、To、に先ほど設定した送信元と送信先を指定します。これでメール(テストメール)の完成です。
そして、メールを送信するためにサーバーに接続します。
smtplib.SMTP()を使って、ホストとポートを指定します。ehlo()でサーバーと通信を開始し、starttls()でセキュアな通信経路を利用します。再度、ehlo()でサーバーに呼びかけるとサーバー側からログイン情報を要求してくるので、login(username, password)で情報を渡します。認証が成功したらsend_message(msg)でメッセージを送信します。完了したらquit()でサーバーを閉じます。
という流れのコードになっています。これをPythonファイルで保存して、ターミナルで実行してみましょう。
Gmailのセキュリティ設定とエラー
おそらく最初の実行ではエラーが出るのではないでしょうか。それはGoogle側がgmailへのアクセスのセキュリティを設定しているため、Pythonのコード実行からログインできないためです。
おそらくGmailにセキュリティ通知が届いていて、「安全性の低いアプリをブロックしました」という情報が表示されるはずです。
ここで、Pythonのコードを実行するために、このセキュリティを回避しておく必要があるので、Googleアカウントの管理画面にアクセスして、「安全性の低いアプリのアクセス」の項目から「安全性の低いアプリの許可」を「有効」に設定します。
これで再度、Pythonコードを受け付けるようになります。この作業は、最初に行っていても良いものです。Googleの提供するアプリにアクセスする時は、このような表示がされるので、必要に応じて設定の許可などをしましょう。
メール送信の確認
Googleのセキュリティの設定を行ったら、このコードを実行してみましょう。
ターミナルから実行した場合は、何も問題が無ければ、数秒待てばプロンプトが再度表示されるはずです。(上のGoogleのセキュリティが効いてブロックされていればエラーが表示されます)
メールが届いているか、送信先のメールボックスを確認してみましょう。
このように、メールが受信できているのが確認できると成功です。
添付ファイルのあるメールを送信する
次は、添付ファイルをつけて、メールを送信するコードを書いてみます。添付するファイルは上のコードをmail_code.pyで同じで作業ディレクトリに保存したものを、テキストファイルとして添付送信してみます。
上のコードを次のように書き換えてみました。
from email import message
from email.mime import multipart # 追加
from email.mime import text # 追加
import smtplib
smtp_host = 'smtp.gmail.com'
smtp_port = 587
from_email = 'fromXXXemail@gmail.com'
to_email = 'toXXXemail@gmail.com'
username = 'fromXXXemail@gmail.com'
password = 'googlepassword'
# msg = message.EmailMessage()
msg = multipart.MIMEMultipart() # こちらでメールオブジェクトを作成
# msg.set_content('これはPythonコードを使ったテストメールの本文です。')
msg['Subject'] = 'test mail_2 from python' # 件名を先ほどと区別
msg['From'] = from_email
msg['To'] = to_email
msg.attach(text.MIMEText('添付ファイルのあるメール送信です。', 'plain')) # こちらでメール本文を記述
with open('mail_code.py', 'r') as f: # 添付ファイルの作成
attachment = text.MIMEText(f.read(), 'plain')
attachment.add_header(
'Content-Disposition', 'attachment',
filename='mail_code.txt'
)
msg.attach(attachment)
server = smtplib.SMTP(smtp_host, smtp_port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(username, password)
server.send_message(msg)
server.quit()
ファイルを添付して送信するには簡単な処理では行えないので、ライブラリを2つ追加してimportしています。
サーバーやポートの情報は同じです。
あとはメール作成の部分が違います。message.EmailMessage() の代わりにmultipart.MIMEMultipart() を利用してメールのオブジェクトを作ります。また、set_content()の代わりに、attach(text.MIMEText()) を使って、テキストを’plain’に指定して、メール本文を記述します。あと、Subjectは先ほどと区別するために少し変更しています。
次に添付ファイルを作成します。withステートメントの構文を使ってファイルを読み込んで作成していきます。withステートメントの使い方は以下で触れています。
with open() を使ってファイルを読み出しモード’r’で開きます。text.MIMEText(f.read(), ‘plain’) を使って、f.read()でデータを読み込み、テキストを’plain’に指定して変数attachmentに格納します。これに、add_header()を使ってヘッダー情報を追加し、mail_code.txtというファイルにします。
msg.attach(attachment)でメールにファイルを添付します。
サーバーの接続処理は先ほどと一緒です。
これを実行しすると、次のようにメールが相手先に送信されます。
添付ファイルも受信しているのがわかります。
一応、ファイルをクリックして見ると次のように表示されます。
先のコードがテキストファイルに書き込まれているのがわかります。
SMTPハンドラーを使ってログをメールで送信する
SMTPハンドラーを使ってログをメールで送信するという方法を行ってみます。
これは本来、ログデータをログ解析ソフトで収集して分析し、まとめてメールで送るというような場合に使いますが、こでは模擬的に直接メールに出力するということをやってみます。
なお、ロギングの詳細については以下の記事を参照してください。
これまでのコードのホスト、ポート、メール情報以外は全て次のように書き換えます。
ここではロギングの出力がCRITICA Lの時にメールを送信する処理をやってみます。
import logging
import logging.handlers
smtp_host = 'smtp.gmail.com'
smtp_port = 587
from_email = 'fromXXXemail@gmail.com'
to_email = 'toXXXemail@gmail.com'
username = 'fromXXXemail@gmail.com'
password = 'googlepassword'
logger = logging.getLogger('Gmail')
logger.setLevel(logging.CRITICAL)
logger.addHandler(logging.handlers.SMTPHandler(
(smtp_host, smtp_port), from_email, to_email,
subject='Send logs by email', credentials=(username, password),
secure=(None, None, None), timeout=20))
logger.info('info')
logger.critical('critical')
ログを取得するのでloggingとhandlersをインポートします。
ホスト情報などはそのままです。
logging.getLogger(‘Gmail’)として名前をとりあえずここではGmailとしてloggerを作ります。これにsetLevel(logging.CRITICAL)としてロギングレベルをCRITICALに設定します。
logger.addHandler(logging.handlers.SMTPHandler())を使って処理を実行していきます。これにホスト情報などの変数を使って、各種引数を渡しています。ホストとポートをタプルで渡し、送信元、送信先のメールアドレス、subjectをSend logs by emailとし、 credentialsでユーザーネームとパスワード、 secureはここではNoneを入れました。timeoutは少し長めに20秒を設定しました。
ロギングの出力を、infoとcriticalに設定します。Pythonのロギングは、デフォルトではINFOは出力されないことになっています。ロギングレベルをCRITICALに先ほど設定したので、このコードを実行すると、メールが送信されることになります。
確認すると次のように受信されます。
受信したメールにはcriticalと出力されているのがわかります。
最後に
ここではGoogleのGmailを使ったメール送信のコードを扱いました。
他の電子メールも設定を変更などするなどすれば、同様の処理を行えるはずです。
ロギングについてもこの期に確認しておくのもいいでしょう。
なお、念のためGoogleアカウントのセキュリティも戻しておきましょう。