【業務自動化】Chapter3-5:メール送信を自動化しよう

ながみえ

一つ前のページでは 残業集計ツール を作成しました。

今回は メール送信の自動化 を行いましょう。

Chapter1:PythonでExcelを操作しよう
Chapter2:PyInstallerで自動化ツール(.exe)作ろう
Chapter3:便利な自動化ツールを5つ作ろう
 ・Chapter3-1:Excelファイルをフォルダ丸ごと結合しよう
 ・Chapter3-2:テンプレートを使った請求書自動作成
 ・Chapter3-3:グラフ付き売上レポート自動生成ツールを作ろう
 ・Chapter3-4:勤怠の丸め・残業集計自動化ツールを作ろう
 ・Chapter3-5:メール送信を自動化しよう ◁今回はここ
Chapter4:Webスクレイピング入門
Chapter5:自動化ツールを作って稼ごう

Excel にまとまったアドレス帳をもとに、一括でメールを送れる仕組みをPythonで作成してみましょう。

もちろん、それは一般のメールソフトにもできる基本的な機能です。しかし、Pythonで自動化することで以下のようなメリットが生まれます。

  • 社内の定型報告や請求書送付を定期的に自動送信できる
  • Webスクレイピング(Chapter4で学習)と組み合わせて、ネット上の情報を自動収集 ⇒ 自動送信できる
  • Excelにある顧客リストから自動で宛先を読み込み、本文を個別にカスタマイズした上で自動送信

本記事で紹介するコードはただの「メールの一括送信ツール」です。これだけではそれほど価値はありません。

しかしこれをベースとして拡張していくことで、実務に役立つ強力な仕組みに発展させられるのが最大の価値です。

<<前のページ

業務自動化の記事一覧

次のページ>>

Pythonでメール送信を自動化する仕組み

Pythonでメールを送るときには、メールソフトを使うわけではなく「プログラムが直接メールサーバーに接続して送信」します。

そのため単純なコマンドだけで済むわけではなく、メールの仕組みや通信のルールをある程度知っておく必要があります。

ここからは、Pythonでのメール送信に必要な基本要素を順に解説します。

まずは「メールの仕組み」「SMTP」「MIMEText」といったキーワードを押さえていきましょう。

あわせて読みたい
openpyxl使える関数・メソッド・クラス一覧【Excel自動化の基本リファレンス】
openpyxl使える関数・メソッド・クラス一覧【Excel自動化の基本リファレンス】
【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

メール配信の仕組みと流れ

普段私たちが使っているメールは、Gmail や Outlook などのアプリを通じて送受信しています。

しかし、アプリが直接相手に届けているわけではなく、必ず「メールサーバー」を介してやり取りが行われます。

送信の流れをシンプルに表すと、次のようになります。

  1. 送信者が書いたメールを、まず自分が利用する送信サーバーに渡す
  2. サーバー同士がやり取りをして、宛先の受信サーバーへ転送する
  3. 受信サーバーに保存されたメールを、受信者が自分のアプリから読み込む

この仕組みを理解しておくと、Pythonでメールを送るときに「プログラムがどの役割を担うのか」が見えてきます。

つまり、Pythonは送信者の代わりに 送信サーバーへ接続してメールを託す 役割を果たします。

SMTPとは|Pythonのsmtplibでサーバーへ送信する基本

SMTP(Simple Mail Transfer Protocol)は、インターネット上でメールを送信するための基本的な通信規格です。

私たちがGmailやOutlookで送ったメールも、裏側では必ずSMTPのルールに従ってサーバーに届けられています。

Pythonでメールを自動送信する際も、プログラムがSMTPサーバーに接続して「誰から誰へ」「件名は何か」「本文はどんな内容か」を指示する必要があります。

そのために使うのが、標準ライブラリに含まれる smtplib です。

今回のサンプルコードでは学習用として、外部にメールを送信するのではなく ローカル環境で起動したダミーSMTPサーバー に接続する仕組みを採用しています。

これにより誤って本物のメールを送ってしまう心配がなく、メールの送信処理を安全に試せます。

MIMETextとは|テキスト/HTML本文と文字エンコードの基礎

メールは単純に「文字列を送りつける」だけでは成立しません。

送信者や宛先、件名、本文といった複数の情報をひとつの「メールメッセージ」として組み立てる必要があります。

そのために利用されるのが MIME(Multipurpose Internet Mail Extensions) という仕組みです。

Pythonでは、標準ライブラリの email.mime.text.MIMETextクラス を使うことで、本文をメール形式に整形できます。これを利用すると:

  • 本文の文字コード(例:UTF-8)を指定できる
  • 本文の種類(プレーンテキストかHTMLか)を選べる
  • サーバーが理解できる「正式なメール構造」として扱える

今回紹介するサンプルコードでは MIMEText(body, "plain", "utf-8") という形で呼び出し、Excelから読み込んだ本文を プレーンテキスト形式 でメールメッセージに変換しています。

こうすることで、件名や送信元と組み合わせた「完成したメール」としてサーバーに渡せるようになります。

【Python】勉強猫がノートパソコンを見ながら考え込む様子。記事内の休憩用イラスト

サンプルスクリプト|openpyxlでExcel→SMTP送信

メール送信自動化のサンプルスクリプトを紹介します。

このサンプルで実現できること

ここからは実際にコードを動かしながら、Excelに記載した宛先リストをもとにメールをまとめて送信する仕組みを学んでいきます。

今回用意しているサンプルスクリプトは、次のような流れで処理を行います。

  1. Excelファイルから宛先・件名・本文を読み込む
    → 1行目はヘッダー、2行目以降をデータとして扱います。
  2. メールメッセージを組み立てる
    MIMEText を利用して本文をメール形式に整形し、件名や宛先を追加します。
  3. SMTPサーバーに接続してメールを送信する
    → 学習用のダミーサーバーに送信し、ターミナルに内容を表示させます。

つまり、このサンプルコードを動かすことで「Excelのリストをもとにメールをまとめて処理する」一連の流れを確認できます。

実際の業務にそのまま使うのではなく、仕組みを理解するための最小限のモデルケースだと考えてください。

送信リストExcelの自動生成スクリプト

サンプルを動かす前に、メール送信に必要な宛先リストをExcelファイルとして準備する必要があります。

手作業で作っても構いませんが、練習用にあらかじめ テスト用Excelを自動生成するスクリプト を用意してあります。

このスクリプトを実行すると、次のような処理が行われます。

  1. プロジェクト内の input フォルダを作成(存在しない場合のみ)
  2. 新しいExcelブックを生成し、シート名を mail_list に設定
  3. 1行目にヘッダーとして「To」「Subject」「Body」を追加
  4. サンプル用の宛先・件名・本文を3件ほど書き込み
  5. 最終的に send_mail_list.xlsx という名前で保存

以下のコードをコピーし、適切な場所に保存して実行してください。

import openpyxl
import pathlib

input_dir = pathlib.Path(__file__).parent / "input"
input_dir.mkdir(exist_ok=True)

# 保存ファイル名
file_name = input_dir / "send_mail_list.xlsx"

# 新規ブック作成
book = openpyxl.Workbook()
sheet = book.active
sheet.title = "mail_list"

# ヘッダー行
sheet.append(["To", "Subject", "Body"])

# サンプルデータ
sample_data = [
    ["user1@example.com", "テスト件名1", "これは本文のテスト1です。"],
    ["user2@example.com", "テスト件名2", "これは本文のテスト2です。"],
    ["user3@example.com", "テスト件名3", "これは本文のテスト3です。"]
]

for row in sample_data:
    sheet.append(row)

# 保存
book.save(file_name)
print(f"{file_name} を作成しました。")

ダミーSMTPサーバーの起動|aiosmtpdで安全に送信テスト

メール送信のコードをいきなり本番のサーバーに接続して試すのは、誤送信のリスクがあるため危険です。

学習段階ではまず ダミーのSMTPサーバー を使い、送信内容を実際には外部に送らず、ターミナルに出力させる方法が安全です。

Pythonにはこれを実現できるモジュールとして aiosmtpd が利用できます。

これは実際のSMTPサーバーと同じように振る舞いますが、受け取ったメールを外部に配送するのではなく、その内容をコンソールに表示するだけです。

まずはこのaiosmtpdを使用するため、コマンドプロンプトにてインストールしましょう。

pip install aiosmtpd

ダミーサーバーを起動するには、ターミナルやコマンドプロンプトで次のコマンドを実行してください。

python -m aiosmtpd -n -l localhost:1025
  • -n : サーバーをフォアグラウンドで動かす(終了は Ctrl+C)
  • -l localhost:1025 : ローカルホストのポート1025で待ち受け

この状態で送信スクリプトを動かすと、実際に外部には送られず、ターミナルに受信したメール内容(宛先、件名、本文)が表示されます。

これにより、安全にコードの挙動を確認できるというわけです。

サンプルスクリプト|MIMETextで本文生成し一斉送信

ここまで準備したExcelファイルとダミーSMTPサーバーを組み合わせて動作させるのが、Chapter3-5_send_mail.py です。

このスクリプトを実行すると、Excelから読み込んだ宛先リストに基づいて、ダミーサーバーにメールを順番に送信していきます。

処理の流れは次のようになっています。

  1. Excelの読み込み
    • send_mail_list.xlsx を開き、2行目以降のデータ(宛先・件名・本文)をリストに格納します。
    • 1行目はヘッダー行としてスキップされます。
  2. メールメッセージの生成
    • MIMEText を使って本文を整形し、件名(Subject)、送信元(From)、宛先(To)を設定します。
    • 送信元はダミーとして noreply@example.com を使用しています。
  3. SMTPサーバーへの送信
    • smtplib.SMTP("localhost", 1025) でローカルに立てたダミーサーバーへ接続。
    • 作成したメッセージを send_message メソッドで送信します。
  4. 完了メッセージ
    • すべての送信処理が終わると「送信テスト完了!」と表示され、ターミナル側に各メールの内容が出力されます。

このスクリプトを実行すれば、「Excelで管理した複数の宛先に、まとめてメールを送る」という自動化の流れを体験できます。

実際の業務で使うにはさらに設定が必要ですが、自作の自動送信ツールを拡張する基礎として非常に重要なステップになります。

import openpyxl, pathlib, sys
import smtplib
from email.mime.text import MIMEText

# === 実行環境に応じた基準ディレクトリ ===
if getattr(sys, 'frozen', False):
    BASE_DIR = pathlib.Path(sys.executable).parent
else:
    BASE_DIR = pathlib.Path(__file__).parent

input_dir = BASE_DIR / "input"

# Excelファイルの読み込み
file_name = input_dir / "send_mail_list.xlsx"
book = openpyxl.load_workbook(file_name)
sheet = book.active

to_list = []
subject_list = []
body_list = []

# 2行目以降を読み込む(1行目はヘッダー)
for row in sheet.iter_rows(min_row=2, values_only=True):
    to_address, subject, body = row
    if not any(row):          # 完全な空行はスキップ
        continue
    if not to_address:        # 宛先がない行はスキップ
        continue
    to_list.append(to_address)
    subject_list.append(subject or "(件名なし)")
    body_list.append(body or "")

# === ダミーSMTPサーバーに送信 ===
# aiosmtpd を別ターミナルで起動しておく: python -m aiosmtpd -n -l localhost:1025
with smtplib.SMTP("localhost", 1025) as server:
    for i in range(len(to_list)):
        msg = MIMEText(body_list[i], "plain", "utf-8")
        msg["Subject"] = subject_list[i]
        msg["From"] = "noreply@example.com"  # ダミー送信元
        msg["To"] = to_list[i]

        # ★ 学習用: コンソールに内容を表示 ★
        print("=== 送信メール ===")
        print("To:", to_list[i])
        print("Subject:", subject_list[i])
        print("Body:", body_list[i])
        print("------------------")

        server.send_message(msg)

print("送信テスト完了!ターミナルにメール内容が出力されています。")

このコードを実行すると、コマンドプロンプトに以下のように出力されます。

---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Subject: =?utf-8?b?44OG44K544OI5Lu25ZCNMQ==?=
From: noreply@example.com
To: user1@example.com
X-Peer: ('::1', 62175, 0, 0)

44GT44KM44Gv5pys5paH44Gu44OG44K544OIMeOBp+OBmeOAgg==
------------ END MESSAGE ------------
---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Subject: =?utf-8?b?44OG44K544OI5Lu25ZCNMg==?=
From: noreply@example.com
To: user2@example.com
X-Peer: ('::1', 62175, 0, 0)

44GT44KM44Gv5pys5paH44Gu44OG44K544OIMuOBp+OBmeOAgg==
------------ END MESSAGE ------------
---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Subject: =?utf-8?b?44OG44K544OI5Lu25ZCNMw==?=
From: noreply@example.com
To: user3@example.com
X-Peer: ('::1', 62175, 0, 0)

44GT44KM44Gv5pys5paH44Gu44OG44K544OIM+OBp+OBmeOAgg==
------------ END MESSAGE ------------

それぞれのメールが MIME形式 で表示されていて、日本語部分は Base64エンコードされています。

本来ならば日本語で読めるように表示したいところですが、Python3.12 以降では 標準ライブラリsmtpd が削除されており、複雑な対応が必要となってしまいました。

上記のように表示されれば送信は成功していますので、このまま以下の内容に進んでください。

【Python】勉強猫がコーヒーを片手にリラックスしている様子。記事内の休憩用イラスト

実運用への応用方法|本番SMTP・Gmail連携・認証の注意点

ここまで紹介したコードは学習用として「ダミーSMTPサーバー」に送信する仕組みになっていました。

そのためターミナルにはメール内容が出力されますが、実際の受信者には届きません。

ここでは、実際に受信者にメールを届ける方法を紹介します。

本番でメールを送るには|SMTPサーバー設定とポート/暗号化

実際にメールを送信するには、次の手順が必要になります。

  1. 利用するSMTPサーバーの情報を取得する
    • 会社のメールサーバーやGmailなどのSMTPホスティングサービスを利用します。
    • 例:Gmailなら「smtp.gmail.com」、ポートは「587」。
  2. 認証情報(ユーザー名・パスワード)を設定する
    • SMTPサーバーは不正利用を防ぐため、必ずログイン認証を行います。
    • 送信者のメールアドレスとパスワードを安全に管理し、プログラムから利用します。
  3. 暗号化通信(TLS/SSL)の利用
    • 通常、ポート587で接続して「STARTTLS」を使い、暗号化した通信に切り替えます。
    • Pythonの smtplib では server.starttls() を呼び出すことで対応できます。

これらを組み合わせることで、サンプルコードを 実際に外部へメールを送れるスクリプト へ拡張できます。

以下のコード(Outlookを使用する例)を参考にしてください。

import pathlib
import sys
import smtplib
import openpyxl
from email.mime.text import MIMEText

# PyInstallerでexe化した場合はsys.executableのパスを基準に、
# 通常の.py実行時は__file__のあるフォルダを基準にする
if getattr(sys, "frozen", False):
    BASE_DIR = pathlib.Path(sys.executable).parent
else:
    BASE_DIR = pathlib.Path(__file__).parent

input_dir = BASE_DIR / "input"

# Excelファイルの読み込み
file_name = input_dir / "send_mail_list.xlsx"
book = openpyxl.load_workbook(file_name)
sheet = book.active

to_list = []
subject_list = []
body_list = []

# 2行目以降を読み込む(1行目はヘッダー)
for row in sheet.iter_rows(min_row=2, values_only=True):
    to_address, subject, body = row

    if to_address is None:
        break

    to_list.append(to_address)
    subject_list.append(subject)
    body_list.append(body)

# OutlookのSMTPサーバー情報
smtp_server = "smtp-mail.outlook.com"
smtp_port = 587

# 送信元アドレスとパスワード
from_address = "あなたのアドレス@outlook.com"
password = "あなたのパスワード"

# Outlook SMTPサーバーに接続して送信
with smtplib.SMTP(smtp_server, smtp_port) as server:
    server.starttls()
    server.login(from_address, password)

    for i in range(len(to_list)):
        msg = MIMEText(body_list[i], "plain", "utf-8")
        msg["Subject"] = subject_list[i]
        msg["From"] = from_address
        msg["To"] = to_list[i]

        server.send_message(msg)

print("メール送信完了!")
勉強猫
勉強猫

注意:このコードを実際に動かすと、本当に相手へメールが届くよ!

最初は必ず 自分自身のアドレスを宛先にしてテストしよう。

Gmailのアプリパスワードについて

GmailをPythonから操作してメールを送信する場合、通常のログインパスワードは利用できません。

Googleはセキュリティ強化のために「安全性の低いアプリからのアクセス」を廃止しており、代わりに アプリパスワード を使う必要があります。

アプリパスワードとは、Googleアカウントの本来のパスワードとは別に発行される、アプリ専用の16桁のパスワードです。

これを使うことで、プログラムから安全にGmailのSMTPサーバーへログインできます。

アプリパスワードを発行する手順

  1. Googleアカウントで 2段階認証を有効化 する
    • アプリパスワードは2段階認証を設定していないと発行できません。
  2. Googleアカウントの「セキュリティ」設定 にアクセスする
  3. 「アプリ パスワード」を選択
  4. アプリ名を「Python」など任意で入力して生成する
  5. 表示された16桁のコードが「アプリパスワード」

プログラムでの利用方法

サンプルコードでは次のように利用します。

from_address = "あなたのメールアドレス@gmail.com"
app_password = "ここに発行した16桁のアプリパスワード"

このアプリパスワードは、Googleアカウント本体のパスワードとは異なり、そのアプリ専用 なので、万が一漏洩しても削除すればすぐに無効化できます。

まとめ|メール送信自動化を使いこなそう

この章では、Pythonを使って Excelのリストからメールを自動送信する方法 を学びました。

ここで紹介したコードそのものは、シンプルに「Excelリストに従ってメールを一括送信する」仕組みです。

しかし、Pythonでメール送信を自動化する価値は拡張性にあります。

  • Excelと連携して個別のメッセージを差し込む
  • 添付ファイル(レポートや請求書)を自動生成して送信する
  • 第4章で学ぶWebスクレイピングと組み合わせて「最新データを取得して自動通知する」

といった応用を行うことで、自分やチームの業務にぴったり合った オリジナルの業務効率化ツール を作り出せるのです。

この章をきっかけに、ぜひ自分のアイデアをPythonで形にしてみてください。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいExcel自動化学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

業務自動化の記事一覧

次のページ>>

記事URLをコピーしました