Gmail Python多个附件

时间:2014-10-27 07:29:22

标签: python gmail email-attachments

我正在尝试创建一个小脚本,使用gmail通过电子邮件发送多个附件。下面的代码发送电子邮件但不发送附件。预期用途是cron一对db查询并通过电子邮件发送结果。由于报告的date位于文件名中,因此每天总会有2个文件和文件名不同。否则我会使用:

part.add_header('Content-Disposition', 
    'attachment; filename="absolute Path for the file/s"')

非常感谢任何帮助。

import os
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.MIMEBase import MIMEBase
from email import Encoders


#Set up crap for the attachments
files = "/tmp/test/dbfiles"
filenames = [os.path.join(files, f) for f in os.listdir(files)]
#print filenames


#Set up users for email
gmail_user = "joe@email.com"
gmail_pwd = "somepasswd"
recipients = ['recipient1','recipient2']

#Create Module
def mail(to, subject, text, attach):
   msg = MIMEMultipart()
   msg['From'] = gmail_user
   msg['To'] = ", ".join(recipients)
   msg['Subject'] = subject

   msg.attach(MIMEText(text))

   mailServer = smtplib.SMTP("smtp.gmail.com", 587)
   mailServer.ehlo()
   mailServer.starttls()
   mailServer.ehlo()
   mailServer.login(gmail_user, gmail_pwd)
   mailServer.sendmail(gmail_user, to, msg.as_string())
   # Should be mailServer.quit(), but that crashes...
   mailServer.close()

#get all the attachments
   for file in filenames:
      part = MIMEBase('application', 'octet-stream')
      part.set_payload(open(file, 'rb').read())
      Encoders.encode_base64(part)
      part.add_header('Content-Disposition', 'attachment; filename="%s"'
                   % os.path.basename(file))
      msg.attach(part)
#send it
mail(recipients,
   "Todays report",
   "Test email",
   filenames)

3 个答案:

答案 0 :(得分:5)

在张贴之前应该再等一个小时。 做了两个改变:

1。)向上移动附件循环

2。)换掉了 part.add_header('Content-Disposition','attachment; filename =“%s”'                    %os.path.basename(file))

for part.add_header('Content-Disposition','attachment; filename =“%s”'%file)

像冠军一样工作。 Gmail包含多个收件人和多个附件。

import os 
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.MIMEBase import MIMEBase
from email import Encoders


#Set up crap for the attachments
files = "/tmp/test/dbfiles"
filenames = [os.path.join(files, f) for f in os.listdir(files)]
#print filenames


#Set up users for email
gmail_user = "joe@email.com"
gmail_pwd = "somepasswd"
recipients = ['recipient1','recipient2']

#Create Module
def mail(to, subject, text, attach):
   msg = MIMEMultipart()
   msg['From'] = gmail_user
   msg['To'] = ", ".join(recipients)
   msg['Subject'] = subject

   msg.attach(MIMEText(text))

   #get all the attachments
   for file in filenames:
      part = MIMEBase('application', 'octet-stream')
      part.set_payload(open(file, 'rb').read())
      Encoders.encode_base64(part)
      part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
      msg.attach(part)

   mailServer = smtplib.SMTP("smtp.gmail.com", 587)
   mailServer.ehlo()
   mailServer.starttls()
   mailServer.ehlo()
   mailServer.login(gmail_user, gmail_pwd)
   mailServer.sendmail(gmail_user, to, msg.as_string())
   # Should be mailServer.quit(), but that crashes...
   mailServer.close()

#send it
mail(recipients,
   "Todays report",
   "Test email",
   filenames)

答案 1 :(得分:1)

谢谢@marc! 我无法评论你的答案,所以这里有一些修正(错误命名的变量)和小改进:

import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email import MIMEImage
from email.mime.base import MIMEBase
from email import Encoders

def mail(to, subject, text, attach):
    # allow either one recipient as string, or multiple as list
    if not isinstance(to,list):
        to = [to]
    # allow either one attachment as string, or multiple as list
    if not isinstance(attach,list):
        attach = [attach]

    gmail_user='username@gmail.com'
    gmail_pwd = "password"
    msg = MIMEMultipart()
    msg['From'] = gmail_user
    msg['To'] = ", ".join(to)
    msg['Subject'] = subject

    msg.attach(MIMEText(text))

    #get all the attachments
    for file in attach:
        print file
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(open(file, 'rb').read())
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
        msg.attach(part)

    mailServer = smtplib.SMTP("smtp.gmail.com", 587)
    mailServer.ehlo()
    mailServer.starttls()
    mailServer.ehlo()
    mailServer.login(gmail_user, gmail_pwd)
    mailServer.sendmail(gmail_user, to, msg.as_string())
    # Should be mailServer.quit(), but that crashes...
    mailServer.close()

if __name__ == '__main__':
    mail(['recipient1', 'recipient2'], 'subject', 'body text',
         ['attachment1', 'attachment2'])

答案 2 :(得分:0)

我有类似的问题。我可以发送多个附件,但是在我的Mac邮件应用程序上,不会显示所有附件,也不会显示html(在Gmail网络上,一切正常。)如果有人遇到相同的问题,则下面的代码对我来说适用于python3.8。现在,所有附件和html都会显示在邮件应用中。

https://docs.python.org/3/library/email.examples.html#email-examples

小更新:

import os, ssl, sys
import smtplib
# For guessing MIME type based on file name extension
import mimetypes
from email.message import EmailMessage
from email.policy import SMTP
from datetime import datetime
from uuid import uuid4

directory = '/path/to/files'
recipients = ['recipient@gmail.com']
sender = 'username@gmail.com'
password = 'password'
email_host, email_port = 'smtp.gmail.com', 465

msg = EmailMessage()
msg['Subject'] = f'This is a subject {datetime.utcnow()}'
msg['To'] = ', '.join(recipients)
msg['From'] = sender
msg.preamble = f'{str(uuid4())}\n'

msg.add_alternative('This is a PLAIN TEXT', subtype='plain')
msg.add_alternative('''\
    <html>
    <head></head>
    <body>
        <h4>Hello World! this is HTML </h4>
        <p style="margin: 0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
        quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat.</p>
    </body>
    </html>''', subtype='html')

for filename in ['sample.pdf', 'sample2.pdf']:
    path = os.path.join(directory, filename)
    if not os.path.isfile(path):
        continue
    # Guess the content type based on the file's extension.  Encoding
    # will be ignored, although we should check for simple things like
    # gzip'd or compressed files.
    ctype, encoding = mimetypes.guess_type(path)
    if ctype is None or encoding is not None:
        # No guess could be made, or the file is encoded (compressed), so
        # use a generic bag-of-bits type.
        ctype = 'application/octet-stream'
    maintype, subtype = ctype.split('/', 1)
    with open(path, 'rb') as fp:
        msg.add_attachment(fp.read(),
                            maintype=maintype,
                            subtype=subtype,
                            filename=filename)

context = ssl.create_default_context()
with smtplib.SMTP_SSL(email_host, email_port, context=context) as server:
    server.login(sender, password)
    server.send_message(msg)