こんにちは、かつコーチです。
処理が終わったら通知メールを送りたい、レポートを毎朝自動送信したい。
そんな場面で活躍するのが、Python標準ライブラリのsmtplib(メール送信プロトコルであるSMTPを扱うライブラリ)です。
この記事では、smtplibを使った基本のメール送信方法から、Gmailでのアプリパスワード設定、認証エラーのトラブルシューティングまでを解説します。
読み終える頃には、Pythonから自動でメールを送信できるようになります。
基本の書き方・実装手順
手順1:SMTPサーバーに接続してメールを送る
smtplibは標準ライブラリなので、追加のインストールは不要です。
メールの本文作成にはemail.mimeモジュールを使います。
import smtplib
from email.mime.text import MIMEText
def send_mail(subject: str, body: str, to_addr: str, from_addr: str, password: str) -> None:
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = from_addr
msg["To"] = to_addr
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(from_addr, password)
server.send_message(msg)
print("メールを送信しました。")
MIMEText(body)で本文を作成し、件名・送信元・送信先をmsgに設定しています。
server.starttls()は、通信を暗号化(TLS)するためのおまじないです。
手順2:Gmailでアプリパスワードを設定する
Gmailのアカウントをそのまま使ってログインしようとすると、セキュリティ設定によりエラーになる場合があります。
Gmailでは、通常のログインパスワードではなくアプリパスワード(アプリ専用に発行する16桁のパスワード)を使う必要があります。
アプリパスワードの発行手順は次の通りです。
- Googleアカウントの管理画面で「セキュリティ」を開く
- 「2段階認証プロセス」を有効にする(未設定の場合は先に設定が必要)
- 「アプリパスワード」を選択し、任意の名前(例:
python-script)を付けて生成する - 表示された16桁の文字列を、スクリプトの
passwordとしてそのまま使う
生成されたアプリパスワードは再表示できないため、安全な場所に控えておきましょう。
手順3:環境変数でパスワードを管理する
パスワードをコードに直接書き込むのはセキュリティ上おすすめできません。
os.environを使って、環境変数からパスワードを読み込む形にします。
import os
import smtplib
from email.mime.text import MIMEText
def send_mail(subject: str, body: str, to_addr: str) -> None:
from_addr = os.environ["GMAIL_ADDRESS"]
password = os.environ["GMAIL_APP_PASSWORD"]
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = from_addr
msg["To"] = to_addr
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(from_addr, password)
server.send_message(msg)
print("メールを送信しました。")
if __name__ == "__main__":
send_mail("処理完了通知", "バッチ処理が正常に終了しました。", "recipient@example.com")
実行前にターミナルで環境変数を設定しておきます。
export GMAIL_ADDRESS="your_account@gmail.com"
export GMAIL_APP_PASSWORD="生成した16桁のアプリパスワード"
つまずきやすい設定・注意点
Gmailの場合、SMTPサーバーはsmtp.gmail.com、ポート番号は587(TLS通信用)を使います。
ポート番号を465にする場合はSMTP_SSLを使うなど、接続方式によって書き方が変わる点に注意してください。
よくあるつまずきポイント・エラー対処
通常のパスワードでログインして認証エラーになる
これは筆者が実際にsmtplibを初めて使ったときに遭遇したつまずきです。
普段Gmailにログインするときと同じパスワードを使ったところ、認証に失敗しました。
❌ Before(通常のログインパスワードを使う書き方)
import smtplib
from email.mime.text import MIMEText
msg = MIMEText("テスト送信です。")
msg["Subject"] = "テスト"
msg["From"] = "your_account@gmail.com"
msg["To"] = "recipient@example.com"
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login("your_account@gmail.com", "普段使っているログインパスワード")
server.send_message(msg)
実行すると、次のエラーメッセージが表示されました。
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted.')
原因は、Googleのセキュリティポリシーにより、通常のパスワードでの外部アプリからのログインがブロックされているためでした。
エラーメッセージからは原因が分かりにくく、パスワードの入力ミスを疑って何度も確認してしまいました。
✅ After(アプリパスワードを使う書き方)
import smtplib
from email.mime.text import MIMEText
msg = MIMEText("テスト送信です。")
msg["Subject"] = "テスト"
msg["From"] = "your_account@gmail.com"
msg["To"] = "recipient@example.com"
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login("your_account@gmail.com", "生成した16桁のアプリパスワード")
server.send_message(msg)
前の章で紹介した手順でアプリパスワードを発行し、そちらをログインに使うことでエラーは解消しました。
2段階認証を有効にしたうえでアプリパスワードを使う、という2段構えの設定が必要な点を、当時の筆者は知りませんでした。
Gmail宛にsmtplibでメールを送る場合は、必ずこの手順を踏むようにしましょう。
まとめ
この記事のポイント
smtplibは標準ライブラリなので追加インストールなしで使えるMIMETextでメール本文・件名・宛先を組み立てる- Gmailでは通常のパスワードではなく、2段階認証+アプリパスワードが必須
- パスワードは環境変数で管理し、コードに直書きしない
- 認証エラーが出た場合は、まずアプリパスワードの設定を疑う
次に読むべき記事
- osモジュールでファイル・ディレクトリを操作する
- スケジュール実行を自動化する(schedule/cron連携)
- requestsライブラリでWebスクレイピングの基本を学ぶ
タグ: Python, 中級者向け, 自動化