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'] = "耶啵学习机" msg['Subject'] = subject msg['Cc'] = "抄送对象" msg.attach(MIMEText('正文:python邮件附件发送测试', 'plain', 'utf-8')) # 附件1 普通文本 att1 = MIMEText(open(r'C:\Users\Foe\Desktop\H2O\移动云运维平台操作步骤.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)
发送excel附件
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内容就是一个图像展示方式的定义。
图片发送
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