python3-邮件发送-不同格式
0x00 邮件格式
要发邮件,总要先了解邮件格式吧,这里指的是邮件的各个部分与python中SMTP所对应的一些必须的格式
0x01 简单发送邮件格式如下:
import smtplib
from email.mime.text import MIMEText
from email.header import Header
mail_host = \'smtp.139.com\'
mail_user = \'xxx@139.com\'
mail_pass = \'xx\'
# 邮件定义区域
msg = MIMEText(\'我是邮件内容\',\'plain\',\'utf-8\') # 邮箱正文内容
msg[\'Subject\'] = \'我是标题\'
# msg[\'From\'] = mail_user # 发件人
msg[\'From\'] = \'发件人自定义\'+\'<\'+mail_user+\'>\'
msg[\'To\'] = \'xxx@139.com,xxx@163.com\' # 收件人
msg[\'Cc\'] = \'xxx@163.com\' # 抄送对象
server = smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_pass)
server.sendmail(msg[\'From\'],msg[\'To\']+msg[\'Cc\'],msg.as_string())
server.quit()
发送效果如下:
0x02 邮件中发送附件
0x21 发送简单文本内容附件
import smtplib
import pandas as pd
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
mail_host = \'smtp.163.com\'
mail_user = \'xxx@163.com\'
mail_pass = \'xx\'
receivers = [\'xxx@139.com\']
def mailsend():
# 创建一个带有附件的实例
msg = MIMEMultipart()
subject = \'标题:邮件附件发送测试\'
msg[\'From\'] = "xxx"
msg[\'To\'] = ",".join(receivers)
msg[\'Subject\'] = subject
msg[\'Cc\'] = "抄送对象"
msg.attach(MIMEText(\'正文:python邮件附件发送测试\', \'plain\', \'utf-8\'))
# 附件1 普通文本
att1 = MIMEText(open(r\'xxx.txt\', \'rb\').read(), _subtype=\'base64\',_charset=\'utf-8\')
att1[\'Content-Type\'] = \'text/plain\'
att1[\'Content-Disposition\'] = \'attachment;filename="test.txt"\'
msg.attach(att1)
server = smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_pass)
server.sendmail(mail_user,receivers,msg.as_string())
server.quit()
0x22 发送excel附件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email import encoders
from email.mime.base import MIMEBase
mail_server = \'smtp.163.com\' # input("请输入邮箱服务器地址:")
mail_user = \'xxx@163.com\' # input("请输入你的邮箱:")
mail_pass = \'xxx\' # input("请输入你的邮箱密码或是授权码")
receivers = [\'xxx@139.com\']
msg = MIMEMultipart() #创建一个邮件实例
msg[\'From\'] = Header(\'管理员<%s>\'% mail_user).encode()
msg[\'To\'] = \',\'.join(receivers)
msg[\'Subject\'] = Header(\'邮件附件发送测试\',\'utf-8\').encode() #邮件标题
msg.attach(MIMEText(body,\'plain\',\'utf-8\')) #邮件正文
# with open(attachment,\'rb\')as f:
# mime = MIMEBase(\'text\',\'txt\',filename=attachment)
# mime.add_header(\'Content-Disposition\',\'attachment\',filename=attachment)
# mime.set_payload(f.read())
# encoders.encode_base64(mime)
# msg.attach(mime)
\'\'\'
text_part = MIMEBase(\'text\', \'plain\')
part = MIMEBase(\'application\', "bitcoin-paymentrequest")
part = MIMEBase("application","zip")
可以看出,不同的文件类型,其发送时的一些格式都不一样,模板不能全部套用
\'\'\'
part = MIMEBase("application","octet-stream")
part.set_payload(open(r"xxx.xls","rb").read())
encoders.encode_base64(part)
part.add_header(\'Content-Disposition\',\'attachment\',filename=attachment)
msg.attach(part)
try:
s = smtplib.SMTP()
s.connect(mail_server)
s.login(mail_user,mail_pass)
s.sendmail(mail_user,receivers,msg.as_string())
s.quit()
except Exception as e:
print(\'错误类型:\',e.__class__.__name__)
print(\'错误明细:\',e)
0x23 邮件发送html附件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr,formataddr
import requests
def getHtml(url):
html = requests.get(url).text
return html
def mailSend(body):
mail_server = \'smtp.163.com\'
mail_user = \'xx@163.com\'
mail_pass = \'xx\'
receivers = [\'xx@139.com\']
msg = MIMEMultipart()
msg[\'From\'] = "好好学习<%s>" % mail_user
msg[\'To\'] = \',\'.join(receivers)
msg[\'Subject\'] = "这是一个发送html附件的邮件~"
msg.attach(MIMEText(body,\'html\',\'utf-8\'))
# try:
link = smtplib.SMTP()
link.connect(mail_server)
link.login(mail_user,mail_pass)
link.sendmail(mail_user,receivers,msg.as_string())
link.quit()
# except Exception as e:
# print("Error:%s" % e)
if __name__ == \'__main__\':
url = "https://www.cnblogs.com/foe0/p/11926083.html"
body = getHtml(url)
mailSend(body)
我这里测试发的内容是自定义的一段;直接读取url发送的,渲染出现了问题,这里不做关注,不是本节要点。
body = \'\'\'
<h1>测试邮件</h1>
<h2 style="color:red">This is a test</h1>
\'\'\'
0x24 邮件发送图片
发送图片时,不定义body文字正文也可以发送出去,但是在邮件中是看不到图片的,这里的body内容就是一个图像展示方式的定义。
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
# 格式化邮件地址
def sendMail(body, image):
smtp_server = \'smtp.163.com\'
from_mail = \'x@163.com\'
mail_pass = \'x\'
to_mail = [\'xx@139.com\',]
msg = MIMEMultipart()
# Header对中文进行转码
msg[\'From\'] = \'管理员 <%s>\' % from_mail
msg[\'To\'] = \',\'.join(to_mail)
msg[\'Subject\'] = Header(\'图片\', \'utf-8\')
msg.attach(MIMEText(body, \'html\', \'utf-8\'))
with open(image,"rb")as f:
pic = MIMEImage(f.read())
pic.add_header(\'Content-ID\',\'<image1>\')
msg.attach(pic)
try:
s = smtplib.SMTP()
s.connect(smtp_server, "25")
s.login(from_mail, mail_pass)
s.sendmail(from_mail, to_mail, msg.as_string()) # as_string()把MIMEText对象变成str
s.quit()
except smtplib.SMTPException as e:
print("Error: %s" % e)
if __name__ == "__main__":
body = \'\'\'
<html><body>
<center>下边是一张图片</center>
<img src="cid:image1" alt="image1" align="center" width=100% >
<center>上边是一张图片</center>
</body></html>
\'\'\'
sendMail(body, \'2.jpg\')
0x03 小结
第一节中邮箱格式的填写也不是一成不变,可以根据需要设定一些内容,但要注意一些格式,本人才疏学浅,不能全部列举出来,如果有报错,别的地方都排查过了,可以考虑这些格式,修改为你认为最为稳妥,不会出错的那一种。
第二节能写的不止这些,不同的文件附件读取方式都不太一样,没必要全部列举完,举一反三。
到这里就告一段落,不得不说,邮件发送还是有点坑的地方,主要是第三方调用时,不明白他的具体判定机制,有时候报错554 垃圾邮件,超过上限(绝对没超)的错误时,要灵活修改,比如说:
把自己加入到收件人或抄送对象中
正文或标题不要出现测试字样,test等等;
还有就是163和QQ邮箱的第三方是另外的授权密码,而非原邮箱密码;
再不能解决的问题只能尝试换个邮箱了,对139我是真没辙了。
以上,若有什么问题欢迎指正。
参考链接:
https://programtalk.com/python-examples/email.MIMEBase.MIMEBase/
https://www.w3school.com.cn/media/media_mimeref.asp
https://blog.csdn.net/weixin_42029733/article/details/86559612
https://blog.csdn.net/xiaosongbk/article/details/60142996