问题:如何使用python smtplib向多个收件人发送电子邮件?
经过大量搜索后,我无法找到如何使用smtplib.sendmail发送给多个收件人的方法。问题是每次发送邮件时,邮件标题似乎都包含多个地址,但实际上只有第一个收件人会收到电子邮件。
问题似乎在于email.Message
模块期望的smtplib.sendmail()
功能与功能不同。
简而言之,要发送给多个收件人,您应该将标题设置为以逗号分隔的电子邮件地址的字符串。但是,该sendmail()
参数to_addrs
应为电子邮件地址列表。
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()
After much searching I couldn’t find out how to use smtplib.sendmail to send to multiple recipients. The problem was every time the mail would be sent the mail headers would appear to contain multiple addresses, but in fact only the first recipient would receive the email.
The problem seems to be that the email.Message
module expects something different than the smtplib.sendmail()
function.
In short, to send to multiple recipients you should set the header to be a string of comma delimited email addresses. The sendmail()
parameter to_addrs
however should be a list of email addresses.
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()
回答 0
这确实有效,我花了大量时间尝试多种变体。
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())
This really works, I spent a lot of time trying multiple variants.
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())
回答 1
的msg['To']
需要是一个字符串:
msg['To'] = "a@b.com, b@b.com, c@b.com"
虽然recipients
in sendmail(sender, recipients, message)
需要是一个列表:
sendmail("a@a.com", ["a@b.com", "b@b.com", "c@b.com"], "Howdy")
The msg['To']
needs to be a string:
msg['To'] = "a@b.com, b@b.com, c@b.com"
While the recipients
in sendmail(sender, recipients, message)
needs to be a list:
sendmail("a@a.com", ["a@b.com", "b@b.com", "c@b.com"], "Howdy")
回答 2
您需要了解电子邮件的可见地址和投递之间的区别。
msg["To"]
本质上是印刷在信件上的东西。它实际上没有任何作用。除了您的电子邮件客户端(与常规邮递员一样)之外,您还将假定这是您要将电子邮件发送给的人。
但是,实际交付可能会大不相同。所以你可以将电子邮件(或副本)放入完全不同的人的邮箱中。
有多种原因。例如转发。的To:
头字段不上转发更改,但是,电子邮件被放入不同的邮箱。
smtp.sendmail
现在,该命令将负责实际交付。email.Message
仅是信件的内容,而不是交货的内容。
在低级中SMTP
,您需要一个个地给接收者一个地址,这就是为什么地址列表(不包括名称!)才是明智的API的原因。
对于标题,它还可以包含例如名称,例如To: First Last <email@addr.tld>, Other User <other@mail.tld>
。因此,不建议您使用代码示例,因为它将无法传递此邮件,因为仅将其拆分给,
您,您仍然没有有效的地址!
You need to understand the difference between the visible address of an email, and the delivery.
msg["To"]
is essentially what is printed on the letter. It doesn’t actually have any effect. Except that your email client, just like the regular post officer, will assume that this is who you want to send the email to.
The actual delivery however can work quite different. So you can drop the email (or a copy) into the post box of someone completely different.
There are various reasons for this. For example forwarding. The To:
header field doesn’t change on forwarding, however the email is dropped into a different mailbox.
The smtp.sendmail
command now takes care of the actual delivery. email.Message
is the contents of the letter only, not the delivery.
In low-level SMTP
, you need to give the receipients one-by-one, which is why a list of adresses (not including names!) is the sensible API.
For the header, it can also contain for example the name, e.g. To: First Last <email@addr.tld>, Other User <other@mail.tld>
. Your code example therefore is not recommended, as it will fail delivering this mail, since just by splitting it on ,
you still not not have the valid adresses!
回答 3
这个对我有用。
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())
It works for me.
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())
回答 4
我尝试了下面的方法,它就像一个魅力:)
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())
I tried the below and it worked like a charm :)
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())
回答 5
所以实际上问题是SMTP.sendmail和email.MIMEText需要两个不同的东西。
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())
So actually the problem is that SMTP.sendmail and email.MIMEText need two different things.
email.MIMEText sets up the “To:” header for the body of the e-mail. It is ONLY used for displaying a result to the human being at the other end, and like all e-mail headers, must be a single string. (Note that it does not actually have to have anything to do with the people who actually receive the message.)
SMTP.sendmail, on the other hand, sets up the “envelope” of the message for the SMTP protocol. It needs a Python list of strings, each of which has a single address.
So, what you need to do is COMBINE the two replies you received. Set msg[‘To’] to a single string, but pass the raw list to sendmail:
emails = ['a.com','b.com', 'c.com']
msg['To'] = ', '.join( emails )
....
s.sendmail( msg['From'], emails, msg.as_string())
回答 6
我想出了这个可导入的模块功能。在此示例中,它使用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()
I came up with this importable module function. It uses the gmail email server in this example. Its split into header and message so you can clearly see whats going on:
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')
将消息发送给所有收件人。抄送和密件抄送收件人的同上。
I figured this out a few months back and blogged about it. The summary is:
If you want to use smtplib to send email to multiple recipients, use email.Message.add_header('To', eachRecipientAsString)
to add them, and then when you invoke the sendmail method, use email.Message.get_all('To')
send the message to all of them. Ditto for Cc and Bcc recipients.
回答 8
下面的解决方案为我工作。它成功地将电子邮件发送给多个收件人,包括“抄送”和“密件抄送”。
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)
The solution below worked for me. It successfully sends an email to multiple recipients, including “CC” and “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)
回答 9
那么,在方法本asnwer方法并没有为我工作。我不知道,也许这是Python3(我正在使用3.4版本)或gmail相关问题,但是经过一番尝试之后,对我有用的解决方案是
s.send_message(msg)
代替
s.sendmail(sender, recipients, msg.as_string())
Well, the method in this asnwer method did not work for me. I don’t know, maybe this is a Python3 (I am using the 3.4 version) or gmail related issue, but after some tries, the solution that worked for me, was the line
s.send_message(msg)
instead of
s.sendmail(sender, recipients, msg.as_string())
回答 10
我使用python 3.6,以下代码对我有用
email_send = 'xxxxx@xxx.xxx,xxxx@xxx.xxx'
server.sendmail(email_user,email_send.split(','),text)
I use python 3.6 and the following code works for me
email_send = 'xxxxx@xxx.xxx,xxxx@xxx.xxx'
server.sendmail(email_user,email_send.split(','),text)
回答 11
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函数。
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')
It only worked for me with send_message function and using the join function in the list whith recipients, python 3.6.
回答 12
您可以在文本文件上写收件人电子邮件时尝试使用此方法
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')
you can try this when you write the recpient emails on a text file
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')