首页 文章

如何发送电子邮件附件?

提问于
浏览
223

我在理解如何使用Python向附件发送电子邮件时遇到问题 . 我已经使用 smtplib 成功通过电子邮件发送了简单消息 . 有人可以解释如何在电子邮件中发送附件 . 我知道网上有其他帖子,但作为Python初学者,我觉得很难理解 .

10 回答

  • 59

    这是另一个:

    import smtplib
    from os.path import basename
    from email.mime.application import MIMEApplication
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.utils import COMMASPACE, formatdate
    
    
    def send_mail(send_from, send_to, subject, text, files=None,
                  server="127.0.0.1"):
        assert isinstance(send_to, list)
    
        msg = MIMEMultipart()
        msg['From'] = send_from
        msg['To'] = COMMASPACE.join(send_to)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject
    
        msg.attach(MIMEText(text))
    
        for f in files or []:
            with open(f, "rb") as fil:
                part = MIMEApplication(
                    fil.read(),
                    Name=basename(f)
                )
            # After the file is closed
            part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
            msg.attach(part)
    
    
        smtp = smtplib.SMTP(server)
        smtp.sendmail(send_from, send_to, msg.as_string())
        smtp.close()
    

    它与第一个例子大致相同......但它应该更容易投入 .

  • 4

    这是我最终使用的代码:

    import smtplib
    from email.MIMEMultipart import MIMEMultipart
    from email.MIMEBase import MIMEBase
    from email import Encoders
    
    
    SUBJECT = "Email Data"
    
    msg = MIMEMultipart()
    msg['Subject'] = SUBJECT 
    msg['From'] = self.EMAIL_FROM
    msg['To'] = ', '.join(self.EMAIL_TO)
    
    part = MIMEBase('application', "octet-stream")
    part.set_payload(open("text.txt", "rb").read())
    Encoders.encode_base64(part)
    
    part.add_header('Content-Disposition', 'attachment; filename="text.txt"')
    
    msg.attach(part)
    
    server = smtplib.SMTP(self.EMAIL_SERVER)
    server.sendmail(self.EMAIL_FROM, self.EMAIL_TO, msg.as_string())
    

    代码与Oli的帖子大致相同 . 谢谢大家

    代码来自Binary file email attachment problem post .

  • 20

    这是来自 Oli for python 3的修改版本

    import smtplib
    import os.path as op
    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    from email.mime.text import MIMEText
    from email.utils import COMMASPACE, formatdate
    from email import encoders
    
    
    def send_mail(send_from, send_to, subject, message, files=[],
                  server="localhost", port=587, username='', password='',
                  use_tls=True):
        """Compose and send email with provided info and attachments.
    
        Args:
            send_from (str): from name
            send_to (str): to name
            subject (str): message title
            message (str): message body
            files (list[str]): list of file paths to be attached to email
            server (str): mail server host name
            port (int): port number
            username (str): server auth username
            password (str): server auth password
            use_tls (bool): use TLS mode
        """
        msg = MIMEMultipart()
        msg['From'] = send_from
        msg['To'] = COMMASPACE.join(send_to)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject
    
        msg.attach(MIMEText(message))
    
        for path in files:
            part = MIMEBase('application', "octet-stream")
            with open(path, 'rb') as file:
                part.set_payload(file.read())
            encoders.encode_base64(part)
            part.add_header('Content-Disposition',
                            'attachment; filename="{}"'.format(op.basename(path)))
            msg.attach(part)
    
        smtp = smtplib.SMTP(server, port)
        if use_tls:
            smtp.starttls()
        smtp.login(username, password)
        smtp.sendmail(send_from, send_to, msg.as_string())
        smtp.quit()
    
  • 323
    from email.MIMEMultipart import MIMEMultipart
    from email.MIMEText import MIMEText
    from email.MIMEImage import MIMEImage
    import smtplib
    
    msg = MIMEMultipart()
    msg.attach(MIMEText(file("text.txt").read()))
    msg.attach(MIMEImage(file("image.png").read()))
    
    # to send
    mailer = smtplib.SMTP()
    mailer.connect()
    mailer.sendmail(from_, to, msg.as_string())
    mailer.close()
    

    改编自here .

  • 54

    我能得到的最简单的代码是:

    #for attachment email
    from django.core.mail import EmailMessage
    
        def attachment_email(request):
                email = EmailMessage(
                'Hello', #subject
                'Body goes here', #body
                'MyEmail@MyEmail.com', #from
                ['SendTo@SendTo.com'], #to
                ['bcc@example.com'], #bcc
                reply_to=['other@example.com'],
                headers={'Message-ID': 'foo'},
                )
    
                email.attach_file('/my/path/file')
                email.send()
    

    它是基于官方Django documentation

  • 4

    Gmail版本,使用Python 3.6(请注意,您需要更改Gmail设置才能通过smtp发送电子邮件:

    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.mime.application import MIMEApplication
    from os.path import basename
    
    
    def send_mail(send_from: str, subject: str, text: str, 
    send_to: list, files= None):
    
        send_to= default_address if not send_to else send_to
    
        msg = MIMEMultipart()
        msg['From'] = send_from
        msg['To'] = ', '.join(send_to)  
        msg['Subject'] = subject
    
        msg.attach(MIMEText(text))
    
        for f in files or []:
            with open(f, "rb") as fil: 
                ext = f.split('.')[-1:]
                attachedfile = MIMEApplication(fil.read(), _subtype = ext)
                attachedfile.add_header(
                    'content-disposition', 'attachment', filename=basename(f) )
            msg.attach(attachedfile)
    
    
        smtp = smtplib.SMTP(host="smtp.gmail.com", port= 587) 
        smtp.starttls()
        smtp.login(username,password)
        smtp.sendmail(send_from, send_to, msg.as_string())
        smtp.close()
    

    用法:

    username = 'my-address@gmail.com'
    password = 'top-secret'
    default_address = ['my-address2@gmail.com'] 
    
    send_mail(send_from= username,
    subject="test",
    text="text",
    send_to= None,
    files= # pass a list with the full filepaths here...
    )
    

    要与任何其他电子邮件提供商一起使用,只需更改smtp配置即可 .

  • 2

    python 3的另一种方式(如果有人正在搜索):

    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.base import MIMEBase
    from email import encoders
    
    fromaddr = "sender mail address"
    toaddr = "receiver mail address"
    
    msg = MIMEMultipart()
    
    msg['From'] = fromaddr
    msg['To'] = toaddr
    msg['Subject'] = "SUBJECT OF THE EMAIL"
    
    body = "TEXT YOU WANT TO SEND"
    
    msg.attach(MIMEText(body, 'plain'))
    
    filename = "fileName"
    attachment = open("path of file", "rb")
    
    part = MIMEBase('application', 'octet-stream')
    part.set_payload((attachment).read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
    
    msg.attach(part)
    
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(fromaddr, "sender mail password")
    text = msg.as_string()
    server.sendmail(fromaddr, toaddr, text)
    server.quit()
    

    确保在您的Gmail帐户中允许“less secure apps

  • 1

    其他答案非常好,但我还是想分享一种不同的方法,以防有人在寻找替代方案 .

    这里的主要区别是使用这种方法,您可以使用HTML / CSS格式化您的消息,这样您就可以获得创意并为您的电子邮件添加一些样式 . 虽然您没有强制使用HTML,但您仍然可以仅使用纯文本 .

    请注意,此功能接受将电子邮件发送给多个收件人,并允许附加多个文件 .

    我只在Python 2上尝试过这个,但我认为它在3上也可以正常工作:

    import os.path
    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.application import MIMEApplication
    
    def send_email(subject, message, from_email, to_email=[], attachment=[]):
        """
        :param subject: email subject
        :param message: Body content of the email (string), can be HTML/CSS or plain text
        :param from_email: Email address from where the email is sent
        :param to_email: List of email recipients, example: ["a@a.com", "b@b.com"]
        :param attachment: List of attachments, exmaple: ["file1.txt", "file2.txt"]
        """
        msg = MIMEMultipart()
        msg['Subject'] = subject
        msg['From'] = from_email
        msg['To'] = ", ".join(to_email)
        msg.attach(MIMEText(message, 'html'))
    
        for f in attachment:
            with open(f, 'rb') as a_file:
                basename = os.path.basename(f)
                part = MIMEApplication(a_file.read(), Name=basename)
    
            part['Content-Disposition'] = 'attachment; filename="%s"' % basename
            msg.attach(part)
    
        email = smtplib.SMTP('your-smtp-host-name.com')
        email.sendmail(from_email, to_email, msg.as_string())
    

    I hope this helps! :-)

  • 0

    下面是我发布的Here和以下链接的组合,这使我更容易附加xlsx文件 . Found Here

    file = 'File.xlsx'
    username=''
    password=''
    send_from = ''
    send_to = 'recipient1 , recipient2'
    Cc = 'recipient'
    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = send_to
    msg['Cc'] = Cc
    msg['Date'] = formatdate(localtime = True)
    msg['Subject'] = ''
    server = smtplib.SMTP('smtp.gmail.com')
    port = '587'
    fp = open(file, 'rb')
    part = MIMEBase('application','vnd.ms-excel')
    part.set_payload(fp.read())
    fp.close()
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', 'attachment', filename='Name File Here')
    msg.attach(part)
    smtp = smtplib.SMTP('smtp.gmail.com')
    smtp.ehlo()
    smtp.starttls()
    smtp.login(username,password)
    smtp.sendmail(send_from, send_to.split(',') + msg['Cc'].split(','), msg.as_string())
    smtp.quit()
    
  • -1
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    import smtplib
    import mimetypes
    import email.mime.application
    
    smtp_ssl_host = 'smtp.gmail.com'  # smtp.mail.yahoo.com
    smtp_ssl_port = 465
    s = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
    s.login(email_user, email_pass)
    
    
    msg = MIMEMultipart()
    msg['Subject'] = 'I have a picture'
    msg['From'] = email_user
    msg['To'] = email_user
    
    txt = MIMEText('I just bought a new camera.')
    msg.attach(txt)
    
    filename = 'introduction-to-algorithms-3rd-edition-sep-2010.pdf' #path to file
    fo=open(filename,'rb')
    attach = email.mime.application.MIMEApplication(fo.read(),_subtype="pdf")
    fo.close()
    attach.add_header('Content-Disposition','attachment',filename=filename)
    msg.attach(attach)
    s.send_message(msg)
    s.quit()
    

    有关说明,您可以使用此链接正确解释https://medium.com/@sdoshi579/to-send-an-email-along-with-attachment-using-smtp-7852e77623

相关问题