922

Python——发送邮件实例

在实际开发当中,有时候就需要用到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 = '接收邮箱地址列表' # ['[email protected]','[email protected]']用于发送多个邮箱
        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 = '接收邮箱地址列表' # ['[email protected]','[email protected]']
        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 = '接收邮箱地址列表' # ['[email protected]','[email protected]']
        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 = "[email protected]";// 发送端账号   
            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 = "[email protected]"; // 发送人
            //string strcc = "[email protected]";//抄送


            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, "发送邮件出错");
            }
        }

    }
}

发表评论

邮箱地址不会被公开。 必填项已用*标注