python smtplib을 사용하여 여러 수신자에게 이메일을 보내는 방법은 무엇입니까?


198

많은 검색을 한 후 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()

1
OP가 자신의 질문에 답변 한 것으로 보입니다 sendmail. 목록이 필요합니다.
Cees Timmerman


Python3을 사용하여 수신자를 반복해야했습니다. for addr in recipients: msg['To'] = addr그런 다음 효과가있었습니다. 여러 할당은 실제로 각각에 새로운 'To'헤더를 추가합니다. 이것은 매우 기이 한 인터페이스이며, 어떻게 시도했는지 설명조차 할 수 없습니다. 나는 이것을 이해하기 전에 subprocess유닉스 sendmail를 절약하기 위해 유닉스 패키지 를 호출하는 것을 고려 하고있었습니다.
mehtunguh

답변:


312

이것은 실제로 작동합니다 . 여러 변형을 시도하는 데 많은 시간을 보냈습니다.

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에게 감사합니다. 파이썬 스크립트에서 이메일을 보내는 데 문제가 있었고이 코드로 이메일을 보낼 수 있습니다.
fear_matrix

5
아래의 Antoine의 의견과 파이썬 문서 docs.python.org/3/library/email-examples.htmlsend_messagesendmail
cardamom

sendmail의 수신자가 각 트래버스에 사용해야합니다. 그렇지 않으면 첫 번째 요소 만 메일을받습니다.
Johnny

2
위에서 언급 한 URL 수정 : docs.python.org/3/library/email.examples.html
David

151

msg['To']문자열이어야합니다 :

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

recipientsin sendmail(sender, recipients, message)은 목록이어야 하지만 :

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

1
이것은 하나의 이상한 디자인 결정입니다smtplib.
Adam Matan

2
recipients목록이 될 필요는 없습니다. 문자열이 제공되면 하나의 요소가있는 목록으로 취급됩니다. msg['To']문자열은 간단히 생략 할 수 있습니다.
Suzana

나는 'a@a.com, b@b.com'이 어떻게 파싱되는지 이해하지 못하므로 첫 번째 주소 만 이메일을 가져옵니다. 그러나 감사합니다! 이것은 대답입니다. 거기에 목록을 넣어야했습니다.
antonavy


44

이메일 의 보이는 주소와 배달 의 차이점을 이해해야합니다 .

msg["To"]본질적으로 편지에 인쇄되어 있습니다. 실제로 아무런 영향을 미치지 않습니다. 전자 우편 클라이언트는 정규 우체국과 마찬가지로 전자 우편을 보낼 사람이라고 가정합니다.

그러나 실제 배송은 상당히 다를 수 있습니다. 그래서 당신 수 있습니다 이메일 (또는 사본)을 완전히 다른 사람의 포스트 박스에 .

여기에는 여러 가지 이유가 있습니다. 예를 들어 전달 . 그만큼To:헤더 필드가 전달에 변경되지 않습니다, 그러나 이메일은 다른 사서함으로 삭제됩니다.

smtp.sendmail명령은 이제 실제 배달을 처리합니다.email.Message배달 내용이 아닌 문자의 내용입니다.

하위 수준 SMTP에서는 수신자에게 하나씩 하나씩 제공해야하므로 주소 목록 (이름 제외)이 합리적인 API입니다.

헤더의 경우 예를 들어 이름을 포함 할 수도 있습니다 To: First Last <email@addr.tld>, Other User <other@mail.tld>. 따라서 코드 예제는 메일을 분할 ,하지 않아도 유효한 주소가 없기 때문에이 메일을 전달 하지 못하므로 권장 하지 않습니다!


2
RFC 2822는 지정된 헤더에 최대 너비 988 자, 권장 너비 78 자입니다. 주소가 너무 많으면 헤더를 "접습니다".
Steve Hunt

실제로 그 이유와 방법을 설명하므로 허용되는 답변이어야합니다.
Serrano

좋은 대답입니다. CC 및 BCC 이메일 필드는 어떻습니까? smtp.send에 CC 및 BCC 이메일도 포함시켜야한다고 가정합니다. 그리고 msg 필드에 CC 목록 만 (BCC 목록은 아님)?
Tagar

예, 그것이 작동하는 방식입니다. 메일 서버는 BCC 필드를 제거 할 가능성이 있지만 (이것은 보이지 않으며 모두 그렇게 생각하지는 않습니다) 파싱하지는 않습니다.
Anony - 무스 - 종료 될

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())

어떤 버전의 파이썬을 사용하고 있습니까? 나는 원래 포스터와 같은 문제를 겪고 있고 나는 파이썬 2.7.9
panofish를

1
단순히 recipients = ['john.doe@example.com','john.smith@example.co.uk']문자열을 만드는 대신 목록을 만들기 위해 분할하는 것이 어떻습니까?
WoJ

msg [ 'To']는 문자열이어야하고 s.sendmail은 (sender, >>> LIST HERE <<<, msg.as_string ())리스트를 가져야하기 때문에 Woj에게 전달됩니다. 보이는 짜증나는만큼 그것은 당신이 두 필드에 대해 하나 개의 동일한 유형 [문자열이나 목록]을 사용할 수 없습니다, 수단이다
파스칼 루이 마리

나를 위해 매력처럼 작동합니다. 파이썬 3.7.3.
Anadyn

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

10

실제로 문제는 SMTP.sendmail과 email.MIMEText가 두 가지 다른 것이 필요하다는 것입니다.

email.MIMEText는 이메일 본문에 대한 "To :"헤더를 설정합니다. 사람에게 결과를 다른 쪽 끝에 표시하는 데만 사용되며 모든 전자 메일 헤더와 마찬가지로 단일 문자열이어야합니다. (실제로 메시지를받는 사람들과 관련이있을 필요는 없습니다.)

반면에 SMTP.sendmail은 SMTP 프로토콜에 대한 메시지의 "봉투"를 설정합니다. 파이썬의 문자열 목록이 필요하며 각 문자열에는 단일 주소가 있습니다.

따라서 귀하가해야 할 일은받은 두 개의 회신을 결합하는 것입니다. 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')모든 수신자에게 메시지를 보내십시오. 참조 및 숨은 참조 수신자에게 적합합니다.


파이썬 3.7은 메시지와 함께 예외를 던졌습니다 : 예외가 발생했습니다 : ValueError 메시지 에 최대 1 개의 To 헤더가있을 수 있습니다
Wojciech Jakubas

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 = [ 'mailid_5', 'mailid_6'] 그렇지 않으면 헤더에 숨은 참조가 bcc의 목적을 무너 뜨립니다. Gmail 및 기타 메일 서버에서 테스트되었습니다.
Wil

@이 경우 어떻게 BCC를 구현할 것입니까?
3pitt

4

글쎄, 이 asnwer 방법의 방법은 저에게 효과적이지 않았습니다. 모르겠습니다. 아마도 이것이 Python3 (3.4 버전을 사용하고 있습니다) 또는 gmail 관련 문제 일지 모르지만 일부 시도 후에 나에게 도움이되는 해결책은 줄이었습니다.

s.send_message(msg)

대신에

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

4

파이썬 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

당신은 텍스트 파일에 recpient 이메일을 쓸 때 이것을 시도 할 수 있습니다

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.