使用 Python 发送电子邮件且 Gmail SMTP 服务器不适用于附件
Sending email with Python and Gmail SMTP server doesn't work with attachment
我正在尝试发送带有 PDF 附件的电子邮件。我定义了下一个函数:
def mail(to, subject, text, attach):
gmail_user = "email@gmail.com"
gmail_name = "name <email@gmail.com>"
gmail_pwd = "password"
msg = MIMEMultipart()
msg['From'] = gmail_name
msg['To'] = to
msg['Subject'] = subject
msg.attach(MIMEText(text))
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % os.path.basename(attach))
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_name, to, msg.as_string())
mailServer.close()
问题是控制台显示如下错误
smtplib.SMTPServerDisconnected: Server not connected
但是,如果我只是将 'msg.as_string' 替换为 "Whatever string",它就可以正常工作。所以我认为当我尝试附加 PDF 文件时会发生此问题。
你能帮帮我吗?
谢谢
我相信你应该改变这个:part = MIMEBase('application', 'pdf')
。
查看 How do I send an email with a .csv attachment using Python 了解如何尝试猜测文件类型。
其他可能的问题:
- 尝试像这样添加 header:
attachment.add_header("Content-Disposition", "attachment",
filename=fileToSend)
- 你在这条线上使用什么编码器?
Encoders.encode_base64(part)
。我认为你应该使用 from email import encoders
然后 encoders.encode_base64(part)
试试这个-
import smtplib
import mimetypes
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
filePath = "fileName.pdf"
From = 'abc@gmail.com'
To = 'xyz@gmail.com'
msg = MIMEMultipart()
msg['From'] = From
msg['To'] = To
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = 'Sample subject'
msg.attach(MIMEText('Sample message'))
try:
smtp = smtplib.SMTP('smtp.gmail.com:587')
smtp.starttls()
smtp.login('abc@gmail.com', '123456')
except:
i = 1
else:
i = 0
if i == 0:
ctype, encoding = mimetypes.guess_type(filePath)
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)
if maintype == 'text':
fp = open(filePath)
# Note: we should handle calculating the charset
part = MIMEText(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'image':
fp = open(filePath, 'rb')
part = MIMEImage(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'audio':
fp = open(filePath, 'rb')
part = MIMEAudio(fp.read(), _subtype=subtype)
fp.close()
else:
fp = open(filePath, 'rb')
part = MIMEBase(maintype, subtype)
part.set_payload(fp.read())
fp.close()
# Encode the payload using Base64
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % filePath)
msg.attach(part)
try:
smtp.sendmail(From, To, msg.as_string())
except:
print "Mail not sent"
else:
print "Mail sent"
smtp.close()
else:
print "Connection failed"
您还可以使用专门用于编写 HTML 电子邮件、内联显示图片和轻松附加文件的软件包!
我指的包是 yagmail 我是 developer/maintainer.
import yagmail
yag = yagmail.SMTP(gmail_name, gmail_pwd)
yag.send('xyz@gmail.com', 'Sample subject', contents = attach)
仅此而已(3 行 vs 69 行)!!
使用 pip install yagmail
获取您的副本。
内容可以是一个列表,您还可以在其中添加文本,但是由于您没有文本,所以您只能将 attach
文件名作为内容,太棒了不是吗?
它读取文件,神奇地确定编码,并附加它:)
我正在尝试发送带有 PDF 附件的电子邮件。我定义了下一个函数:
def mail(to, subject, text, attach):
gmail_user = "email@gmail.com"
gmail_name = "name <email@gmail.com>"
gmail_pwd = "password"
msg = MIMEMultipart()
msg['From'] = gmail_name
msg['To'] = to
msg['Subject'] = subject
msg.attach(MIMEText(text))
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % os.path.basename(attach))
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_name, to, msg.as_string())
mailServer.close()
问题是控制台显示如下错误
smtplib.SMTPServerDisconnected: Server not connected
但是,如果我只是将 'msg.as_string' 替换为 "Whatever string",它就可以正常工作。所以我认为当我尝试附加 PDF 文件时会发生此问题。
你能帮帮我吗?
谢谢
我相信你应该改变这个:part = MIMEBase('application', 'pdf')
。
查看 How do I send an email with a .csv attachment using Python 了解如何尝试猜测文件类型。
其他可能的问题:
- 尝试像这样添加 header:
attachment.add_header("Content-Disposition", "attachment", filename=fileToSend)
- 你在这条线上使用什么编码器?
Encoders.encode_base64(part)
。我认为你应该使用from email import encoders
然后encoders.encode_base64(part)
试试这个-
import smtplib
import mimetypes
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
filePath = "fileName.pdf"
From = 'abc@gmail.com'
To = 'xyz@gmail.com'
msg = MIMEMultipart()
msg['From'] = From
msg['To'] = To
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = 'Sample subject'
msg.attach(MIMEText('Sample message'))
try:
smtp = smtplib.SMTP('smtp.gmail.com:587')
smtp.starttls()
smtp.login('abc@gmail.com', '123456')
except:
i = 1
else:
i = 0
if i == 0:
ctype, encoding = mimetypes.guess_type(filePath)
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)
if maintype == 'text':
fp = open(filePath)
# Note: we should handle calculating the charset
part = MIMEText(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'image':
fp = open(filePath, 'rb')
part = MIMEImage(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'audio':
fp = open(filePath, 'rb')
part = MIMEAudio(fp.read(), _subtype=subtype)
fp.close()
else:
fp = open(filePath, 'rb')
part = MIMEBase(maintype, subtype)
part.set_payload(fp.read())
fp.close()
# Encode the payload using Base64
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % filePath)
msg.attach(part)
try:
smtp.sendmail(From, To, msg.as_string())
except:
print "Mail not sent"
else:
print "Mail sent"
smtp.close()
else:
print "Connection failed"
您还可以使用专门用于编写 HTML 电子邮件、内联显示图片和轻松附加文件的软件包!
我指的包是 yagmail 我是 developer/maintainer.
import yagmail
yag = yagmail.SMTP(gmail_name, gmail_pwd)
yag.send('xyz@gmail.com', 'Sample subject', contents = attach)
仅此而已(3 行 vs 69 行)!!
使用 pip install yagmail
获取您的副本。
内容可以是一个列表,您还可以在其中添加文本,但是由于您没有文本,所以您只能将 attach
文件名作为内容,太棒了不是吗?
它读取文件,神奇地确定编码,并附加它:)