こんにちは、ライターの遠藤です!
今日は、pythonでメールを送る方法について紹介致します!
「pythonを使って自動的にメールを送信したい。」
「日本語のメールを送ろうとしたらエラーになってしまった。」
「添付ファイルってどうやって付ければいい?」
といった問題を抱えている方へ向けて、
【基礎】pythonでメールを送る方法
【基礎】日本語でメールを送る方法
【応用】ファイルを添付する方法
について、それぞれサンプルコードを紹介致します。
本記事をご活用いただければ、基本的には宛先等の値を変えるだけでメールを送信できるかと思います。
ぜひ、最後までお付き合いください!
なお、本記事はGmailを送信することを仮定しています。
なお、Pythonの記事については、こちらにまとめています。
pythonでメールを送る方法
それでは早速、pythonでメールを送る為のサンプルコードを紹介します。
import smtplib from email.mime.text import MIMEText from email.utils import formatdate FROM = 'from.address@gmail.com' #送信元メールアドレス PASSWORD = 'password' #送信元アカウントのパスワード PORT = 587 #メールを送る際のポート番号(変更不要) TO = 'to.address@gmail.com' #宛先 BCC = 'bcc.address@gmail.com' #s別宛先 SUBJECT = 'subject' #メールタイトル BODY = 'message' #メール本文 def create_mail(from_addr, to_addr, bcc_addr, subject, body): #メール作成メソッド mail = MIMEText(body) # 以下で宛先等情報を入力 mail["From"] = from_addr mail['To'] = to_addr mail['Bcc'] = bcc_addr mail['Subject'] = subject mail['Date'] = formatdate() return mail def send_mail(to_addrs, mail): #メール送信メソッド smtpobj = smtplib.SMTP('smtp.gmail.com', PORT) smtpobj.ehlo() smtpobj.starttls() #暗号化 smtpobj.ehlo() smtpobj.login(FROM, PASSWORD) #アカウントにログイン smtpobj.sendmail(FROM, to_addrs, mail.as_string()) #作成したメールを送信 smtpobj.close() if __name__ == '__main__': #メイン処理 mail = create_mail(FROM, TO, BCC, SUBJECT, BODY) send_mail(TO, mail)
それぞれのエンティティの値は適切に変更し上記コードを実行いただくと、メールを送信することができます。
処理のポイントは以下になります。
1. create_mailメソッドでメールのボディを作成する
宛先(複数宛も)やタイトル、本文はここで作成しています。
ポイントはメソッドのはじめにMIMEText()を呼ぶ点です。
2. send_mailメソッドでメール送信処理を行う
ここではsmtplib.SMTP()を呼ぶ必要があります。
SMTPは「Simple Mail Transfer Protocol」の略で、宛先となる相手のメールサーバへメールを送る為のプロトコルを言います。
引数の’smtp.gmail.com’はGmailのメールサーバへアクセスするという意味があり、PORT(=587)は接続する際のポート番号を指しています。
次に大事なポイントとして、starttls()を呼んだ後にログイン処理をする事です。
これにより暗号化通信でログインすることができます。
これらの処理の最後にsendmail()することでメールを実際に送り、相手にメールが届きます。
日本語でメールを送る方法
上記の方法でメールを送信する際、日本語を入力すると適切に送れない場合があります。
日本語の文章で送信したい場合は、以下のように実装しましょう。
import smtplib from email.mime.text import MIMEText from email.utils import formatdate FROM = 'from.address@gmail.com' PASSWORD = 'password' PORT = 587 TO = 'to.address@gmail.com' BCC = 'bcc.address@gmail.com' SUBJECT = '日本語の題名' BODY = '日本語の本文 def create_msg(from_addr, to_addr, bcc_addr, subject, body): msg = MIMEText(body.encode('iso-2022-jp'), 'plain', 'iso-2022-jp') msg["From"] = from_addr msg['To'] = to_addr msg['Bcc'] = bcc_addr msg['Subject'] = subject msg['Date'] = formatdate() return msg def send_mail(to_addrs, msg): smtpobj = smtplib.SMTP('smtp.gmail.com', PORT) smtpobj.ehlo() smtpobj.starttls() smtpobj.ehlo() smtpobj.login(FROM, PASSWORD) smtpobj.sendmail(FROM, to_addrs, msg.as_string()) smtpobj.close() if __name__ == '__main__': msg = create_msg(FROM, TO, BCC, SUBJECT, BODY) send_mail(TO, msg)
ポイントは1点、MIMEText()を呼び出す時に日本語に対応させるだけです。
これで日本語の文章でも送信が可能になります。
ファイルを添付する方法
続いて、ファイルを添付させる方法を紹介します。
ここでは、jpgファイルを送信してみましょう。
import os import smtplib import mimetypes from email import encoders from email.mime.text import MIMEText from email.mime.base import MIMEBase from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.utils import formatdate ACCOUNT = 'from@gmail.com' PASSWORD = 'password' PORT = 587 TO = 'to@gmail.com' SUBJECT = 'gmail subject' MESSAGE = 'gmail test.' def open_file(path, mode): path = os.path.abspath(path) try: with open(path, mode) as file: data = file.read() except: print ("Error can not reading file") exit() return data def set_attachment(mail, attach_file): #ファイル添付メソッド path = attach_file['path'] mime, encoding = mimetypes.guess_type(path) mtype, msubtype = mime.split('/') if mtype == 'text': data = open_file(path, "r") attachment = MIMEText(data, _subtype=msubtype) elif mtype == 'image': data = open_file(path, "rb") attachment = MIMEImage(data, _subtype=msubtype) else: attachment = MIMEBase(mtype, msubtype) attachment.set_payload(data) Encoders.encode_base64(attachment) attachment.add_header('Content-Disposition','attachment', filename=attach_file['name']) mail.attach(attachment) return mail def create_mail(from_address, to_address, subject, message): #メール作成メソッド mail = MIMEMultipart() body = MIMEText(message) body["From"] = from_address body['To'] = to_address body['Subject'] = subject body['Date'] = formatdate() mail.attach(body) return mail def send_mail(to_addrs, mail): #メール送信メソッド smtpobj = smtplib.SMTP('smtp.gmail.com', PORT) smtpobj.starttls() smtpobj.ehlo() smtpobj.login(ACCOUNT, PASSWORD) smtpobj.sendmail(ACCOUNT, to_addrs, mail.as_string()) smtpobj.close() if __name__ == '__main__': #実行 #本文作成 mail = create_mail(ACCOUNT, TO, SUBJECT, MESSAGE) #ファイルを添付 attach_file = {'name':'sample.jpg', 'path':'./attach/sample.jpg'} mail = set_attachment(mail, attach_file) #送信 send_mail(TO, mail)
ここでは、set_attachmentメソッドで添付ファイルをセットしています。
その際に以下の点にご注意ください。
・pegのようなイメージタイプではMIMEImage()を呼ぶ
・csvファイルなどのテキストタイプではMIMEText()を呼ぶ
また、add_headerのfilenameでファイル名を設定しています。
メールが送信できない場合
最後に、実際にメールを送信しようとした際にエラーが出た時の対処方を紹介致します。
メール送信をしようとした際、最も多くなるのが以下のようなエラーです。
Please log in vian5.7.14 your web browser and then try again.
この場合、以下のような原因が考えられます。
1. パスワードが間違っている
2. Gmailのセキュリティにひっかかっている
1の場合はメールアドレス、パスワードが正しいかを確認してください。
2の場合、以下の対処をすることで送信できるようになります。
①こちらから設定画面へ行き、グーグルアカウントへのアクセスを許可する。
②こちらから設定画面へ行き、「安全性の低いアプリの許可」を「有効」にする
Googleの最新のAPIは認証にOAuth2というものが必要となっており、これがない場合は安全性の低いアプリと認識されます。
今回はPythonの標準ライブラリの範囲で実装されておりこれに対応することができない為、「安全性の低いアプリの許可」を「有効」に設定する必要があります。
まとめ
いかがでしたでしょうか?
今回の記事では、
【基礎】pythonでメールを送る方法
【基礎】日本語でメールを送る方法
【応用】ファイルを添付する方法
について紹介しました!
pythonでメールを送信する方法は簡単なようで難しい部分が多くあります。
検索してもあまり出なかったり、参考書に記載されていなかったりと調べるのが難しい部分がままある為、なかなか進まない事もあるでしょう。
そんな時、本記事が少しでもご参考になりましたら幸いです。