Отправка одного письма с 3-мя разными вложениями python 3 - PullRequest
0 голосов
/ 12 сентября 2018

Я просто хочу отправить электронное письмо с 3-мя CSV-файлами. Когда я запускаю его, пытаясь найти решение, которое нашел здесь, он дает мне файл BIN вместо 3 файлов. Или, попробовав другое решение, он отправит только последний из 3 файлов. Когда я запускаю приведенный ниже код, он дает мне TypeError: add.header () принимает 3 позиционных аргумента, но 4 были даны.

Я понимаю, что это можно сделать с помощью функции, но я не уверен, как заставить все три файла в нее вытянуть. Я провел много часов, пытаясь понять это.

Размещение здесь - мое последнее средство. Я ценю любую помощь в поиске решения.

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

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Ниже приведен простой фрагмент, который я использовал для отправки электронного письма нескольким людям с несколькими вложенными файлами.

# -*- 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')
0 голосов
/ 12 сентября 2018

Обновленное проверенное решение:

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 (так как все вложения находятся в одном списке) должно быть достаточно.

...