发送带有 3 个不同附件的单个电子邮件 python 3

Sending single email with 3 different attachments python 3

我只想发送一封包含 3 个 csv 文件附件的电子邮件。当我到达 运行,尝试我在此处找到的解决方案时,它给了我一个 BIN 文件而不是 3 个文件。或者,尝试另一种解决方案,它只会发送 3 个文件中的最后一个。当我 运行 下面的代码时,它给我 TypeError: add.header() takes 3 positional arguments but 4 were given.

我知道这可以通过一个函数来完成,但我不确定如何让它将所有三个文件都拉入其中。我花了很多时间试图弄清楚。

把它贴在这里是我最后的选择。感谢您在寻找解决方案方面提供的任何帮助。

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import time
import os

msg = MIMEMultipart()
msg['From'] = EMAIL_FROM
msg['To'] = ", ".join(RECIPIENT_LIST)
msg['Subject'] = 'Louisiana Contractors List'

#email content
message = """<html>
<body>
Attached is the Louisiana Contractors Spreadsheet.
<br><br>

Let me know if you have any questions

</body>
</html>
"""

msg.attach(MIMEText(message, 'html'))

files = [
    'C:/Users/rkrouse/Downloads/search-results.csv',
    'C:/Users/rkrouse/Downloads/search-results(1).csv',
    'C:/Users/rkrouse/Downloads/search-results(2).csv']

for a_file in files:
    attachment = open(a_file, 'rb')
    part = MIMEBase('application','octet-stream')
    part.set_payload((attachment).read())
    part.add_header('Content-Disposition', 'attachment', a_file = os.path.basename('C:/Users/rkrouse/Downloads/search-results.csv'))
    encoders.encode_base64(part)
    msg.attach(part)

for a_file in files:
    attachment = open(a_file, 'rb')
    part = MIMEBase('application','octet-stream')
    part.set_payload((attachment).read())
    part.add_header('Content-Disposition', 'attachment', a_file = os.path.basename('C:/Users/rkrouse/Downloads/search-results(1).csv'))
    encoders.encode_base64(part)
    msg.attach(part)

for a_file in files:
    attachment = open(a_file, 'rb')
    part = MIMEBase('application','octet-stream')
    part.set_payload(attachment.read())
    part.add_header('Content-Disposition', 'attachment', a_file = os.path.basename('C:/Users/rkrouse/Downloads/search-results(2).csv'))
    encoders.encode_base64(part)
    msg.attach(part)

#sends email
smtpserver = smtplib.SMTP(EMAIL_SERVER, EMAIL_PORT)
smtpserver.sendmail(EMAIL_FROM, RECIPIENT_LIST, msg.as_string())
smtpserver.quit()

更新测试解决方案:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import time
import os

msg = MIMEMultipart()
msg['From'] = EMAIL_FROM
msg['To'] = ", ".join(RECIPIENT_LIST)
msg['Subject'] = 'Louisiana Contractors List'

#email content
message = """<html>
<body>
Attached is the Louisiana Contractors Spreadsheet.
<br><br>

Let me know if you have any questions

</body>
</html>
"""

msg.attach(MIMEText(message, 'html'))

files = [
    'C:/Users/rkrouse/Downloads/search-results.csv',
    'C:/Users/rkrouse/Downloads/search-results(1).csv',
    'C:/Users/rkrouse/Downloads/search-results(2).csv']

for a_file in files:
    attachment = open(a_file, 'rb')
    file_name = os.path.basename(a_file)
    part = MIMEBase('application','octet-stream')
    part.set_payload(attachment.read())
    part.add_header('Content-Disposition',
                    'attachment',
                    filename=file_name)
    encoders.encode_base64(part)
    msg.attach(part)

#sends email

smtpserver = smtplib.SMTP(EMAIL_SERVER, EMAIL_PORT)
smtpserver.sendmail(EMAIL_FROM, RECIPIENT_LIST, msg.as_string())
smtpserver.quit()

如您所见,您需要指定 base64 编码的文件名。 您还对文件进行了三次迭代。

一个for循环用于遍历列表、集合、数组等。一个for循环(因为所有附件都在一个列表中)应该足够了。

以下是我用来向多个人发送带有多个文件附件的电子邮件的简单片段。

# -*- coding: utf-8 -*-

import smtplib
import mimetypes
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
import ntpath

sender_address = 'vijay.anand@xxxx.com'
default_subject = 'Test email from {}'.format(sender_address)
smtp_server_address = '10.111.41.25'
smtp_port_number = 25

default_message = message = """<html>
<body>
Attached is the Louisiana Contractors Spreadsheet.
<br><br>

Let me know if you have any questions

</body>
</html>
"""


def send_by_smtp(to=None, cc=None, bcc=None, subject=None, attachments=None, attachment_type='plain'):
    """
        Snippet to send an email to multiple people along with multiple attachments.
        :param to: list of emails
        :param cc: list of emails
        :param bcc: list of emails
        :param subject: Email Subject
        :param attachments: list of file paths
        :param attachment_type: 'plain' or 'html'
        :return: None
    """
    email_from = sender_address
    email_to = list()
    files_to_send = attachments
    msg = MIMEMultipart()
    msg["From"] = email_from
    if to:
        to = list(set(to))
        email_to += to
        msg["To"] = ', '.join(to)
    if cc:
        cc = list(set(cc))
        email_to += cc
        msg["Cc"] = ', '.join(cc)
    if bcc:
        bcc = list(set(bcc))
        email_to += bcc
        msg["Bcc"] = ', '.join(bcc)
    if subject:
        msg["Subject"] = subject
        msg.preamble = subject
    else:
        msg["Subject"] = default_subject
        msg.preamble = default_subject

    body = default_message
    msg.attach(MIMEText(body, attachment_type))

    if files_to_send:
        for file_to_send in files_to_send:
            content_type, encoding = mimetypes.guess_type(file_to_send)
            if content_type is None or encoding is not None:
                content_type = "application/octet-stream"
            maintype, subtype = content_type.split("/", 1)
            if maintype == "text":
                with open(file_to_send) as fp:
                    # Note: we should handle calculating the charset
                    attachment = MIMEText(fp.read(), _subtype=subtype)
            elif maintype == "image":
                with open(file_to_send, "rb") as fp:
                    attachment = MIMEImage(fp.read(), _subtype=subtype)
            elif maintype == "audio":
                with open(file_to_send, "rb")as fp:
                    attachment = MIMEAudio(fp.read(), _subtype=subtype)
            else:
                with open(file_to_send, "rb") as fp:
                    attachment = MIMEBase(maintype, subtype)
                    attachment.set_payload(fp.read())
                encoders.encode_base64(attachment)
            attachment.add_header("Content-Disposition", "attachment", filename=ntpath.basename(file_to_send))
            msg.attach(attachment)

    try:
        smtp_obj = smtplib.SMTP(host=smtp_server_address, port=smtp_port_number, timeout=300)
        smtp_obj.sendmail(from_addr=email_from, to_addrs=list(set([email_from] + email_to)), msg=msg.as_string())
        print("Successfully sent email to {}".format(str(email_to)))
        smtp_obj.quit()
        return True
    except smtplib.SMTPException:
        print("Error: unable to send email")
        return False


if __name__ == '__main__':
    print('Send an email using Python')
    result = send_by_smtp(to=['vijay@xxxx.com', 'tha@xxx.com'],
                          cc=['anandp@xxxx.com', 'nitha@xxxx.com'],
                          bcc=['vij@xxxx.com', 'Sun@xxxx.com'],
                          subject='Louisiana Contractors List',
                          attachments=['test.txt', '1.JPG', '2.PNG', '3.PNG', '4.PNG'],
                          attachment_type='html')
    if result:
        print('Email Sent Successfully')
    else:
        print('Email Sending Failed')