在实际开发当中,有时候就需要用到Python发送一些代码构造的邮件信息,最近刚好有接触到这一块,就顺便总结一下。
1、发html、plain格式邮件,不带附件
# -*- coding: UTF-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from email.header import Header
class SendMail(object):
def __init__(self, mail_title, mail_contain):
#初始化发送者与接收者邮箱
self.sender = '发送邮箱地址'
self.accepter = '接收邮箱地址列表' # ['1@xx.com','2@xx.com']用于发送多个邮箱
self.mail_title = mail_title # 邮件标题
self.mail_contain = mail_contain # 邮件内容
def send_data(self):
print('邮件发送中....')
try:
msg = MIMEText(self.mail_contain, 'html', 'utf-8') # 内容, 格式, 编码,这里现在是发送html格式
msg['From'] = formataddr(["发件人邮箱昵称", self.sender])
msg['To'] = ";".join(self.accepter) # 以分号拼接使得群发邮件
msg['Subject'] = self.mail_title #标题
server = smtplib.SMTP_SSL("smtp.qq.com", 465) # 这里以QQ邮箱为例
server.login(self.sender, "邮箱授权码") # 登录邮箱后可以获取
server.sendmail(self.sender, self.accepter, msg.as_string()) #发送
server.quit() # 退出
except Exception as e:
print(e, '发送失败....')
2、发送带附件的邮件
class SendMail(object):
def __init__(self, mail_title, mail_contain):
#初始化发送者与接收者邮箱
self.sender = '发送邮箱地址'
self.accepter = '接收邮箱地址列表' # ['1@xx.com','2@xx.com']
self.mail_title = mail_title
self.mail_contain = mail_contain
def send_data(self):
print('邮件发送中....')
try:
#创建一个带附件的实例
message = MIMEMultipart()
message['From'] = formataddr(["发件人邮箱昵称", self.sender]) # 格式化发件人
message['To'] = ";".join(self.accepter) # 多人抄送
subject = self.mail_title # 邮件标题
message['Subject'] = Header(subject, 'utf-8')
#邮件正文内容
message.attach(MIMEText(self.mail_contain, 'plain', 'utf-8'))
# 构造附件1,传送当前目录下的 data.txt 文件
att1 = MIMEText(open('data.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="data.txt"'
message.attach(att1)
# 构造附件2,传送当前目录下的 test01.txt 文件
att2 = MIMEText(open('test01.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="test01.txt"'
message.attach(att2)
server = smtplib.SMTP_SSL("smtp.qq.com",465)
server.login(self.sender, "邮箱授权码")
server.sendmail(self.sender, self.accepter, message.as_string())
server.quit()
print('发送成功')
except Exception as e:
print(e, '发送失败....')
3、在HTML文本中添加图片(读取本地图片)
class SendMail(object):
def __init__(self, mail_title, mail_contain):
#初始化发送者与接收者邮箱
self.sender = '发送邮箱地址'
self.accepter = '接收邮箱地址列表' # ['1@xx.com','2@xx.com']
self.mail_title = mail_title
self.mail_contain = mail_contain
def send_data(self):
print('邮件发送中....')
try:
message = MIMEMultipart('related')
message['From'] = formataddr(["发件人邮箱昵称", self.sender]) # 格式化发件人
message['To'] = ";".join(self.accepter) # 多人抄送
subject = self.mail_title # 邮件标题
message['Subject'] = Header(subject, 'utf-8')
msgAlternative = MIMEMultipart('alternative')
message.attach(msgAlternative)
mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.lhcx821.com/">木木测试</a></p>
<p>图片演示:</p>
<p><img src="cid:image1"></p>
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))
# 指定图片为当前目录
fp = open('Demo.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header('Content-ID', '<image1>')
message.attach(msgImage)
server = smtplib.SMTP_SSL("smtp.qq.com",465)
server.login(self.sender, "邮箱授权码")
server.sendmail(self.sender, self.accepter, message.as_string())
server.quit()
print('发送成功')
except Exception as e:
print(e, '发送失败....')
可能在发送邮件期间会出现以下报错:
a)报错:Error: A secure connection is requiered(such as ssl):
解决:因为邮箱SSL验证的问题,因此把smtplib.SMTP()改成smtplib.SMTP_SSL(),端口号为465
b)报错:535, b’Error: authentication failed’:
解决:可能是由于用户名不正确,因此代码中的用户名应该填写为邮箱地址@前面部分 ,或是在邮箱设置的帐户昵称
c)SMTP服务器可根据发送的邮箱做相应的选择,如代码中使用163邮箱则设为mail_host = “smtp.qq.com” :
解决:可以设置成"smtp.126.com"、smtp.163.com、"smtp.qq.com"等等
d)代码中的密码mail_pass为授权码,并非邮箱密码,授权码用于登录第三方邮件客户端的专用密码:
解决:QQ邮箱可通过设置→帐户→生成授权码;网易邮箱126/163可通过设置→客户端授权密码
e)之前测试从QQ邮箱发送到163邮箱会被识别为垃圾邮件而被拒收。所以最好收发邮件的邮箱要同类。
最后附加一下C#的发邮实例,换汤不换药:
using System;
using System.Net.Mail;
namespace send_email
{
class Program
{
static void Main(string[] args)
{
SendMailUse();
}
public static void SendMailUse()
{
string host = "smtp.qq.com";// 邮件服务器smtp.qq.com表示QQ邮箱服务器
string userName = "xxxxxx@qq.com";// 发送端账号
string password = "aygxddqaigomdjfg";// 发送端密码(这个客户端重置后的密码):授权码
SmtpClient client = new SmtpClient();
client.DeliveryMethod = SmtpDeliveryMethod.Network;//指定电子邮件发送方式
client.Host = host;//邮件服务器
client.UseDefaultCredentials = true;
client.Credentials = new System.Net.NetworkCredential(userName, password);//用户名、密码
string strfrom = userName;
string strto = "xxxxx@qq.com"; // 发送人
//string strcc = "xxxxxx@qq.com";//抄送
string subject = "C#邮件发送测试-标题";//邮件的主题
string body = "测试邮件内容";//发送的邮件正文
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.From = new MailAddress(strfrom, "xyf");
msg.To.Add(strto);
//msg.CC.Add(strcc);
msg.Subject = subject;//邮件标题
msg.Body = body;//邮件内容
msg.BodyEncoding = System.Text.Encoding.UTF8;//邮件内容编码
msg.IsBodyHtml = true;//是否是HTML邮件
msg.Priority = MailPriority.High;//邮件优先级
try
{
client.Send(msg);
Console.WriteLine("发送成功");
}
catch (System.Net.Mail.SmtpException ex)
{
Console.WriteLine(ex.Message, "发送邮件出错");
}
}
}
}