我正在尝试创建一个小脚本,使用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)
答案 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)