अजगर smtplib का उपयोग करके कई प्राप्तकर्ताओं को ईमेल कैसे भेजें?


197

बहुत खोज के बाद मुझे पता नहीं चल पाया कि कैसे 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
ऐसा प्रतीत होता है कि ओपी ने अपने सवाल का जवाब दिया: sendmailएक सूची की आवश्यकता है।
सीस टिमरमैन


पायथन 3 का उपयोग करके मुझे प्राप्तकर्ताओं के माध्यम से लूप करना पड़ा; for addr in recipients: msg['To'] = addrऔर फिर इसने काम किया। एकाधिक असाइनमेंट वास्तव में प्रत्येक के लिए एक नया 'टू' हेडर जोड़ते हैं। यह एक बहुत ही विचित्र इंटरफ़ेस है, मैं यह भी नहीं बता सकता कि मैंने इसे कैसे आजमाया। इससे पहले कि मैं यह पता लगाता मैं अपनी पवित्रता को बचाने के 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। मुझे अजगर स्क्रिप्ट से एक ईमेल भेजने में समस्या हो रही थी और इस कोड के साथ, अब मैं ईमेल भेज सकता हूं।
डर_मेट्रिक्स

5
यदि आप Antoine की टिप्पणी के अनुसार और Python डॉक्स docs.python.org/3/library/email-examples.htmlsend_messagesendmail
इलायची

आपको प्रत्येक ट्रैवर्स के लिए उपयोग करना होगा जो भेजने वाले के लिए प्राप्त करता है, अन्यथा केवल पहला तत्व मेल प्राप्त करेगा।
जॉनी

2
उपरोक्त उल्लिखित सुधार: docs.python.org/3/library/email.examples.html
डेविड

150

msg['To']स्ट्रिंग होने की आवश्यकताएं:

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

जबकि recipients में sendmail(sender, recipients, message)जरूरत है एक सूची होने के लिए:

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

1
यह एक अजीब डिजाइन निर्णय हैsmtplib.
एडम मटन जूल

2
recipientsएक सूची होने की आवश्यकता नहीं है - यदि एक स्ट्रिंग दी जाती है, तो इसे एक तत्व के साथ एक सूची के रूप में माना जाता है। msg['To']स्ट्रिंग बस छोड़ा जा सकता है।
सुजाना

मुझे वास्तव में समझ नहीं आ रहा है कि कैसे 'a@a.com, b@b.com' को पार्स किया जाता है ताकि केवल पहले पते पर ही ईमेल मिले। लेकिन धन्यवाद! यह उत्तर है, सूची को वहां रखना था।
एनटोनवी

मेरे लिए काम किया, और यह दस्तावेज़ में docs.python.org/2/library/email-examples.html
Rodrigo Laguna

44

आपको ईमेल के दृश्य पते और वितरण के बीच के अंतर को समझने की आवश्यकता है ।

msg["To"]अनिवार्य रूप से पत्र पर छपा है। इसका वास्तव में कोई प्रभाव नहीं पड़ता है। सिवाय इसके कि आपके ईमेल क्लाइंट, नियमित पोस्ट ऑफिसर की तरह, यह मान लेंगे कि यह वही है जिसे आप ईमेल भेजना चाहते हैं।

हालांकि वास्तविक वितरण काफी अलग काम कर सकता है। तो आप कर सकते हैं किसी को पूरी तरह से अलग की पोस्ट बॉक्स में ईमेल (या एक प्रतिलिपि) छोड़ देते हैं।

इसके कई कारण हैं। उदाहरण के लिए अग्रेषणTo:हेडर फ़ील्ड अग्रेषण पर परिवर्तन नहीं करता है, फिर भी ईमेल अलग मेलबॉक्स में छोड़ा जाता है।

smtp.sendmailआदेश अब का ख्याल रखता है वास्तविक वितरण।email.Messageकेवल पत्र की सामग्री है, वितरण नहीं।

निम्न-स्तर में SMTP, आपको प्राप्तकर्ताओं को एक-एक करके देने की आवश्यकता है, यही कारण है कि एड्रेसेस की एक सूची (नामों सहित नहीं!) समझदार एपीआई है।

हेडर के लिए, इसमें उदाहरण के लिए नाम भी शामिल हो सकता है, जैसे To: First Last <email@addr.tld>, Other User <other@mail.tld>इसलिए आपका कोड उदाहरण अनुशंसित नहीं है , क्योंकि यह इस मेल को वितरित करने में विफल हो जाएगा, क्योंकि बस इसे ,आप पर विभाजित करके अभी भी मान्य विज्ञापन नहीं हैं!


2
RFC 2822 किसी दिए गए हेडर के लिए अधिकतम 988 वर्ण और 78 वर्णों की अनुशंसित चौड़ाई लगाता है। यदि आपको बहुत अधिक पते हैं तो आपको हेडर को "फोल्ड" करना होगा।
स्टीव हंट

यह स्वीकृत उत्तर होना चाहिए, क्योंकि यह वास्तव में क्यों और कैसे की व्याख्या करता है।
सेरानो

बहुत बढ़िया जवाब। CC और BCC ईमेल फ़ील्ड के बारे में क्या? मुझे लगता है कि हमें smtp.send में CC और BCC ईमेल भी शामिल करना होगा। और संदेश क्षेत्रों में केवल सीसी सूची (और बीसीसी सूची नहीं)?
तगार

हाँ, यह है कि यह कैसे काम करता है। मेल सर्वर संभवतः बीसीसी फ़ील्ड को छोड़ देंगे (इसे दिखाई देने से रोकने के लिए, और मुझे नहीं लगता कि वे सभी ऐसा करते हैं), लेकिन वे इसे पार्स नहीं करेंगे।
QUIT - Anony-Mousse

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
panfish

1
बस recipients = ['john.doe@example.com','john.smith@example.co.uk']इसे एक स्ट्रिंग बनाने के बजाय क्यों नहीं , और फिर इसे एक सूची बनाने के लिए विभाजित करें?
WoJ

Woj के लिए, क्योंकि msg ['To'] एक स्ट्रिंग होना चाहिए और s.sendmail में एक सूची होनी चाहिए: (प्रेषक, >>> LIST HERE <<<, msg.as_string ())। इसका मतलब है, जितना कष्टप्रद दिखता है, कि आप दोनों क्षेत्रों के लिए एक ही प्रकार [स्ट्रिंग या सूची] का उपयोग नहीं कर सकते हैं
पास्कल लुई-मेरी

मेरे लिए एक आकर्षण की तरह काम करता है। पायथन 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 प्रोटोकॉल के लिए संदेश का "लिफाफा" सेट करता है। इसे स्ट्रिंग की पायथन सूची की आवश्यकता है, जिनमें से प्रत्येक का एक ही पता है।

तो, आपको जो करने की आवश्यकता है वह आपके द्वारा प्राप्त दो उत्तरों को शुद्ध करना है। संदेश ['टू'] एक स्ट्रिंग में सेट करें, लेकिन भेजने के लिए कच्ची सूची पास करें:

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 प्राप्तकर्ताओं के लिए Ditto।


पायथॉन 3.7 संदेश के साथ एक अपवाद फेंकता है: अपवाद हुआ है: ValueError एक संदेश में अधिकतम 1 हेडर हो सकता है
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 को छुपाने के लिए आपको BCC लाइन bcc = ['mailid_5', 'mailid_6' को छोड़ना होगा अन्यथा यह हैडर में दिखाएगा कि bcc के उद्देश्य को पराजित करेगा। जीमेल और अन्य मेल सर्वर के साथ परीक्षण किया गया।
Wil

@ आप उस मामले में बीसीसी को कैसे लागू करेंगे?
3pitt 15

4

खैर, इस asnwer विधि में विधि मेरे लिए काम नहीं किया। मुझे नहीं पता, शायद यह पायथन 3 है (मैं 3.4 संस्करण का उपयोग कर रहा हूं) या जीमेल से संबंधित मुद्दा है, लेकिन कुछ प्रयासों के बाद, मेरे लिए काम करने वाला समाधान लाइन था

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।


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')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.