python smtplibを使用して複数の受信者にメールを送信する方法


196

多くの検索を行った後、smtplib.sendmailを使用して複数の受信者に送信する方法を見つけることができませんでした。問題は、メールが送信されるたびにメールヘッダーに複数のアドレスが含まれているように見えるが、実際には最初の受信者だけがメールを受信することでした。

問題は、email.Messageモジュールがsmtplib.sendmail()関数とは異なる何かを期待していることです。

つまり、複数の受信者に送信するには、ヘッダーをカンマ区切りの電子メールアドレスの文字列に設定する必要があります。ただし、sendmail()パラメーターto_addrsはEメール・アドレスのリストでなければなりません。

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
import smtplib

msg = MIMEMultipart()
msg["Subject"] = "Example"
msg["From"] = "me@example.com"
msg["To"] = "malcom@example.com,reynolds@example.com,firefly@example.com"
msg["Cc"] = "serenity@example.com,inara@example.com"
body = MIMEText("example email body")
msg.attach(body)
smtp = smtplib.SMTP("mailhost.example.com", 25)
smtp.sendmail(msg["From"], msg["To"].split(",") + msg["Cc"].split(","), msg.as_string())
smtp.quit()

1
OPが彼自身の質問に答えたようです:sendmailリストが必要です。
Cees Timmerman、


Python3を使用して、受信者をループする必要がありました。 for addr in recipients: msg['To'] = addrそしてそれは働いた。複数の割り当ては、実際にはそれぞれに新しい「To」ヘッダーを追加します。これは非常に奇妙なインターフェースであり、私がそれを試そうと思った方法を説明することすらできません。私がこれを理解する前に、私が正気を守るためにsubprocessunix sendmailパッケージを呼び出すのに使用することさえ考えていました。
mehtunguh

回答:


311

これは本当に機能します。複数のバリアントを試すのに長い時間を費やしました。

import smtplib
from email.mime.text import MIMEText

s = smtplib.SMTP('smtp.uk.xensource.com')
s.set_debuglevel(1)
msg = MIMEText("""body""")
sender = 'me@example.com'
recipients = ['john.doe@example.com', 'john.smith@example.co.uk']
msg['Subject'] = "subject line"
msg['From'] = sender
msg['To'] = ", ".join(recipients)
s.sendmail(sender, recipients, msg.as_string())

3
ドキュメントは例を持っている:tolist =["one@one.org","two@two.org","three@three.org","four@four.org"]
chug2k

2
このスクリプトをありがとう@sorin Pythonスクリプトからメールを送信する際に問題が発生しました。このコードを使用して、メールを送信できます。
fear_matrix 2015

5
以下のAntoineのコメントやPython docs docs.python.org/3/library/email-examples.htmlsend_messagesendmail
cardamom

sendmailの受信者がトラバースごとに使用する必要があります。そうしないと、最初の要素のみがメールを受信します。
ジョニー


150

msg['To']文字列である必要があります:

msg['To'] = "a@b.com, b@b.com, c@b.com"

一方recipientssendmail(sender, recipients, message)リストする必要があります:

sendmail("a@a.com", ["a@b.com", "b@b.com", "c@b.com"], "Howdy")

1
これは奇妙な設計上の決定の1つですsmtplib.
Adam Matan 2015

2
recipientsリストである必要はありません。文字列が指定された場合、1つの要素を持つリストとして扱われます。msg['To']文字列は、単純に省略することができます。
スザナ

「a@a.com、b@b.com」がどのように解析されるのか、私にはよくわかりません。最初のアドレスだけがメールを受け取ります。しかし、ありがとう!これが答えです、そこにリストを置かなければなりませんでした。
antonavy 2016年


43

メールの表示アドレスと配信の違いを理解する必要があります。

msg["To"]本質的に手紙に印刷されているものです。実際には効果はありません。メールクライアントは、通常の郵便局員と同様に、これがメールの送信先であると想定します。

ただし、実際の配信はかなり異なる場合があります。したがって、メール(またはコピー)をまったく別の人のポストボックスにドロップできます。

これにはさまざまな理由があります。たとえば、転送To:ヘッダフィールドは転送に変更されません、しかし、電子メールが別のメールボックスにドロップされます。

smtp.sendmailコマンドは現在の面倒を実際に配信。email.Message配達ではなく、手紙の内容のみです。

低レベルSMTPでは、受信者に1人ずつ与える必要があるため、アドレスのリスト(名前を含まない!)が賢明なAPIです。

ヘッダーについては、たとえば名前を含めることもできますTo: First Last <email@addr.tld>, Other User <other@mail.tld>そのため、このメールの配信に失敗するため、コード例はお勧めできません。分割するだけで,は、まだ有効なアドレスがないためです。


2
RFC 2822は、特定のヘッダーに最大988文字の幅を課し、推奨される幅は78文字です。アドレスが多すぎる場合は、ヘッダーを必ず「折りたたむ」必要があります。
スティーブハント

これは実際に理由と方法を説明しているため、受け入れられる答えになるはずです。
セラーノ2016

すばらしい答えです。CCおよびBCCの電子メールフィールドはどうですか?また、smtp.sendにCCおよびBCCメールを含める必要があると思います。そして、メッセージフィールドのCCリストのみ(BCCリストではない)?
Tagar

はい、そうです。メールサーバーはBCCフィールドをドロップする可能性があります(これが表示されないようにするためです。すべてがそうだとは思わないでしょう)が、解析はしません。
QUITあり-Anony-Mousse 2017年

19

わたしにはできる。

import smtplib
from email.mime.text import MIMEText

s = smtplib.SMTP('smtp.uk.xensource.com')
s.set_debuglevel(1)
msg = MIMEText("""body""")
sender = 'me@example.com'
recipients = 'john.doe@example.com,john.smith@example.co.uk'
msg['Subject'] = "subject line"
msg['From'] = sender
msg['To'] = recipients
s.sendmail(sender, recipients.split(','), msg.as_string())

どのバージョンのpythonを使用していますか?元のポスターと同じ問題が発生し、python 2.7.9を使用しています
2017年

1
単にrecipients = ['john.doe@example.com','john.smith@example.co.uk']文字列にするのではなく、それを分割してリストを作成するのではないのですか?
WoJ 2019

Wojへ。これは、msg ['To']が文字列であり、s.sendmailがリストを持つ必要があるためです:(sender、>>> LIST HERE <<<、msg.as_string())。つまり、見た目が面倒なのは、両方のフィールドに同じ型[文字列またはリスト]を使用できないことです
Pascal Louis-Marie

私にとっては魅力のように機能します。Python 3.7.3。
アナディン

11

私は以下を試しました、そしてそれは魅力のように働きました:)

rec_list =  ['first@example.com', 'second@example.com']
rec =  ', '.join(rec_list)

msg['To'] = rec

send_out = smtplib.SMTP('localhost')
send_out.sendmail(me, rec_list, msg.as_string())

以下のFYR全体の単純なコード: import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText sender = 'myEmailAddress@example.com' rec_list = ['first@example.com', 'second@example.com'] rec = ', '.join(rec_list) msg = MIMEMultipart('alternative') msg['Subject'] = 'The required subject' msg['From'] = sender msg['To'] = rec html = ('whatever html code') htm_part = MIMEText(html, 'html') msg.attach(htm_part) send_out = smtplib.SMTP('localhost') send_out.sendmail(sender, rec_list, msg.as_string()) send_out.quit()
MasterMind 2017年

10

つまり実際には、SMTP.sendmailとemail.MIMETextには2つの異なるものが必要なのです。

email.MIMETextは、電子メールの本文に「To:」ヘッダーを設定します。結果を相手に表示するためにのみ使用され、すべての電子メールヘッダーと同様に、単一の文字列である必要があります。(実際にメッセージを受信する人とは何の関係もないことに注意してください。)

一方、SMTP.sendmailは、SMTPプロトコルのメッセージの「エンベロープ」を設定します。文字列のPythonリストが必要です。各文字列は単一のアドレスを持っています。

だから、あなたがする必要があるのはあなたが受け取った二つの返事を結合することです。msg ['To']を単一の文字列に設定しますが、生のリストをsendmailに渡します。

emails = ['a.com','b.com', 'c.com']
msg['To'] = ', '.join( emails ) 
....
s.sendmail( msg['From'], emails, msg.as_string())

7

このインポート可能なモジュール関数を思いつきました。この例では、Gmailメールサーバーを使用しています。ヘッダーとメッセージに分割されているため、何が起こっているのかを明確に確認できます。

import smtplib

def send_alert(subject=""):

    to = ['email@one.com', 'email2@another_email.com', 'a3rd@email.com']
    gmail_user = 'me@gmail.com'
    gmail_pwd = 'my_pass'
    smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(gmail_user, gmail_pwd)
    header = 'To:' + ", ".join(to) + '\n' + 'From: ' + gmail_user + '\n' + 'Subject: ' + subject + '\n'
    msg = header + '\n' + subject + '\n\n'
    smtpserver.sendmail(gmail_user, to, msg)
    smtpserver.close()

7

私は数か月前にこれを理解し、それについてブログに書いた。要約は次のとおりです。

smtplibを使用して複数の受信者にメールを送信する場合は、を使用email.Message.add_header('To', eachRecipientAsString)してそれらを追加し、sendmailメソッドを呼び出すときにuse email.Message.get_all('To')、すべての受信者にメッセージを送信します。CcおよびBcc受信者の同上。


Python 3.7がメッセージ付きの例外をスローします:例外が発生しました:ValueError メッセージには最大で1 Toヘッダーが存在する可能性があります
Wojciech Jakubas '19

6

以下の解決策が私にとってうまくいきました。「CC」および「BCC」を含む複数の受信者に電子メールを正常に送信します。

toaddr = ['mailid_1','mailid_2']
cc = ['mailid_3','mailid_4']
bcc = ['mailid_5','mailid_6']
subject = 'Email from Python Code'
fromaddr = 'sender_mailid'
message = "\n  !! Hello... !!"

msg['From'] = fromaddr
msg['To'] = ', '.join(toaddr)
msg['Cc'] = ', '.join(cc)
msg['Bcc'] = ', '.join(bcc)
msg['Subject'] = subject

s.sendmail(fromaddr, (toaddr+cc+bcc) , message)

1
これは部分的に機能し、BCCを本当に非表示にするには、BCC行bcc = ['mailid_5'、 'mailid_6']を省略する必要があります。そうしないと、ヘッダーに表示され、bccの目的を無効にします。Gmailやその他のメールサーバーでテスト済み。
Wil

その場合、BCCをどのように実装しますか?
ピット

4

さて、このasnwerメソッドのメソッドは私にはうまくいきませんでした。わからない、たぶんこれはPython3(3.4バージョンを使用しています)またはGmailに関連する問題ですが、何度か試した後、うまくいった解決策は次のとおりでした

s.send_message(msg)

の代わりに

s.sendmail(sender, recipients, msg.as_string())

4

私はpython 3.6を使用しており、次のコードでうまくいきます

email_send = 'xxxxx@xxx.xxx,xxxx@xxx.xxx'
server.sendmail(email_user,email_send.split(','),text)    

3
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def sender(recipients): 

    body = 'Your email content here'
    msg = MIMEMultipart()

    msg['Subject'] = 'Email Subject'
    msg['From'] = 'your.email@gmail.com'
    msg['To'] = (', ').join(recipients.split(','))

    msg.attach(MIMEText(body,'plain'))

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login('your.email@gmail.com', 'yourpassword')
    server.send_message(msg)
    server.quit()

if __name__ == '__main__':
    sender('email_1@domain.com,email_2@domain.com')

これは、send_message関数を使用して、受信者python 3.6のリストでjoin関数を使用する場合にのみ機能しました。


0

あなたはテキストファイルに受信者の電子メールを書くときにこれを試すことができます

from email.mime.text import MIMEText
from email.header import Header
import smtplib

f =  open('emails.txt', 'r').readlines()
for n in f:
     emails = n.rstrip()
server = smtplib.SMTP('smtp.uk.xensource.com')
server.ehlo()
server.starttls()
body = "Test Email"
subject = "Test"
from = "me@example.com"
to = emails
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] =  Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
text = msg.as_string()
try:
   server.send(from, emails, text)
   print('Message Sent Succesfully')
except:
   print('There Was An Error While Sending The Message')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.