【问题标题】:How to email unique attachments to multiple unique recipients using Python?如何使用 Python 将唯一附件通过电子邮件发送给多个唯一收件人?
【发布时间】:2019-08-01 08:56:37
【问题描述】:

我正在编写一个自动化 Python 脚本。我的目的是将多个唯一附件通过电子邮件发送给多个唯一收件人。例如,我有 1000 条独特的报表,必须通过电子邮件发送给 1000 位独特的客户。我希望我的 Python 脚本能够自动选择附件并将其发送给正确的收件人!

我已经创建了脚本并创建了 pdf 附件并在收件人的每个电子邮件地址之后命名它们,以便我可以使用名称来选择附件并将其与收件人的电子邮件相匹配。 它完美地选择了附件,但它在每次迭代中不断增加对用户的附件的问题..

 #1.READING FILE NAMES WHICH ARE EMAIL ADDRESS FOR RECEPIENTS
 import os, fnmatch
 filePath = "C:/Users/DAdmin/Pictures/"

def readFiles(path):

fileNames =fnmatch.filter(os.listdir(path), '*.pdf')
i=0
pdfFilesNamesOnly=[]
while i < len(fileNames):
    s =fileNames[i]
    removeThePdfExtension= s[0:-4]
    pdfFilesNamesOnly.append(removeThePdfExtension)
    i+=1

return pdfFilesNamesOnly
-----------------------------------------------------------
#2.SENDING AN EMAIL WITH UNIQUE ATTACHMENT TO MULTIPLE UNIQUE RECEPIENTS 

import smtplib
import mimetypes
from optparse import OptionParser
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication
import os,fnmatch
from readFileNames import readFiles

filePath = "C:/Users/DAdmin/Pictures/"

listOfEmails= readFiles(filePath)# Files are named after emails 

def sendEmails(listOfFiNames): #sends the email

    email = 'goddietshe@gmail.com' # Your email
    password = '#####' # Your email account password

    send_to_list = listOfEmails# From the file names

#creating a multipart object
    subject ="MONTHLY STATEMENTS"
    mg = MIMEMultipart('alternative')
    mg['From'] = email
    mg['To'] = ",".join(send_to_list)
    mg['Subject'] = subject
    mg.attach(MIMEText("Please receive your monthly statement",'plain'))

   # Attaching a file now before emailing. (Where l have a problem)

    for i in listOfEmails:
       if i in send_to_list: 
            newFile = (i+'.pdf') # create the name of   the attachment to email using the name(which is the email) and will be used to pick the attachment

            with open(newFile,'rb') as attachment:
                part = MIMEBase('application','x- pdf')
                part.set_payload(attachment.read())
                attachment.close()
            encoders.encode_base64(part)
            part.add_header('Content- Disposition','attachment; filename="%s"' % newFile )

            mg.attach(part)
            text =mg.as_string() # converting the  message obj to a string/text obj

            server = smtplib.SMTP('smtp.gmail.com', 587)        # Connect to the server
            server.starttls() # Use TLS

            server.login(email, password) # Login to the email server

            # this is where it is emailing stuff
            server.sendmail(email, i , text) # Send the email
            server.quit() # Logout of the email server
            print("The mail was sent")


    #print("Failed ")

sendEmails(listOfFiNames)

我希望它能自动将每个唯一附件通过电子邮件发送给 1000 个唯一收件人

【问题讨论】:

  • “但它在每次迭代中不断增加对用户的依恋的问题......” - 你能详细说明一下吗?我不明白你的意思。
  • 啊,我想我知道了。您正在使用相同的 mg 对象,而不是删除以前的附件。
  • 使用 mg.set_payload 替换内容 - 但请记住,您必须添加文本内容以及新附件!
  • 感谢您的快速反馈。但是我还是不清楚你刚才说了什么?!

标签: python email


【解决方案1】:

您重复使用mg(消息),仅使用attach,因此您的附件堆积如山。您需要使用 set_payload 将整个先前的内容替换为新内容,因为没有“删除”方法。

在执行此操作时,您必须记住重新添加您在循环之前设置的文本:

mg.attach(MIMEText("Please receive your monthly statement",'plain'))
for i in listOfEmails:

因为使用set_payload 会丢失之前附加的所有部分。我只是将其保存为变量,然后将其添加到循环中。

此外:

mg['To'] = ",".join(send_to_list)

此行使所有消息都发送给所有人。您还需要将此部分移动到循环中,一次只设置一个电子邮件地址。


编辑应用这些更改:

def sendEmails(): #sends the email

    email = 'goddietshe@gmail.com' # Your email
    password = '#####' # Your email account password

    #creating a multipart object
    subject ="MONTHLY STATEMENTS"
    mg = MIMEMultipart('alternative')
    mg['From'] = email
    # mg['To'] = ",".join(listOfEmails) # NO!
    mg['Subject'] = subject

    text_content = MIMEText("Please receive your monthly statement",'plain')) #safe it for later, rather than attach it - we'll have to re-attach it every loop run

    for i in listOfEmails:
       if i in send_to_list: 
            newFile = (i+'.pdf') # create the name of   the attachment to email using the name(which is the email) and will be used to pick the attachment

            with open(newFile,'rb') as attachment:
                part = MIMEBase('application','x- pdf')
                part.set_payload(attachment.read())
                attachment.close()
            encoders.encode_base64(part)
            part.add_header('Content- Disposition','attachment; filename="%s"' % newFile )

            mg.set_payload(text_content) #change the whole content into text only (==remove previous attachment)
            mg.attach(part) #keep this - new attachment
            mg["To"] = i # send the email to the current recipient only!
            text =mg.as_string() # converting the  message obj to a string/text obj

            server = smtplib.SMTP('smtp.gmail.com', 587)        # Connect to the server
            server.starttls() # Use TLS

            server.login(email, password) # Login to the email server

            # this is where it is emailing stuff
            server.sendmail(email, i , text) # Send the email
            server.quit() # Logout of the email server
            print("The mail was sent")

【讨论】:

  • h4z3 ,如果您能举个例子,我将不胜感激。我没有遵循您的解释,尤其是在 set_payload() 部分。也许是我不理解那里的语义
  • @gsoft 添加了应用更改的功能。请与您的比较,并在代码中阅读我的 cmets。 ;) 可能还有一些问题需要解决,但您的问题只是关于附件堆积。
  • 它返回一个 TypeError: 'Attach is not valid on a message with a non-multipart payload'。来自我们保存附件的行
【解决方案2】:
 **Works very fine like this. Thanks @h4z3**

 def sendEmail():
    email = 'goddietshetu@gmail.com' # Your email
    password = '####' # Your email account password
    subject ="MONTHLY STATEMENTS"

    #creating a multipart object
    mg = MIMEMultipart('alternative')
    mg['From'] = email
    mg['Subject'] = subject

    # attaching a file now


    listOfEmails = readFileNames(filePath)
for i in listOfEmails:
    attachment  =open(i+'.pdf','rb')

    part = MIMEBase('application','octet-stream')
    part.set_payload(attachment.read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition',f"attachment; filename=  {i}.pdf")

    mg.set_payload(mg.attach(MIMEText("",'plain')))
    mg.attach(MIMEText("Please receive your monthly statement",'plain'))
    mg.attach(part)
    mg['To'] = i


    text =mg.as_string() # converting the message obj to a string/text obj

    server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
    server.starttls() # Use TLS
    server.login(email, password) # Login to the email server
    server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email serv
print("The mail was sent")
sendEmail()

【讨论】:

    猜你喜欢
    • 2015-11-30
    • 2019-06-17
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 2018-11-19
    相关资源
    最近更新 更多