述尔

^


使用 Python 和 sendmail 服务给用户发送邮件

碎碎念 • 阅读: 5733

Python 的 smtplib 库通过对 SMTP 协议简单的封装为用户提供了一种很方便的发送电子邮件的途径。

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

由于服务器状态的监控需求,我使用该库做了一个简单的邮件发送程序,配合上一期的网站自动备份 Shell 脚本,实现备份成功后发送邮件通知。

Python 创建 SMTP 对象,语法如下:

import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

参数说明:

host: SMTP 服务器主机。 你可以指定主机的 ip 地址或者域名如: smtp.qq.com,这个是可选参数。
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 默认端口号为25,但主流邮件服务商大都采用 465 端口。
local_hostname: 如果 SMTP 在你的本机上,你只需要指定服务器地址为 localhost 即可。

Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

参数说明:

from_addr: 邮件发送者地址。
to_addrs: 字符串列表,邮件发送地址。
msg: 发送消息

这里要注意一下第三个参数,msg 是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。

实例:

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
 
import smtplib
from email.mime.text import MIMEText
from email.header import Header
 
sender = 'from@tespera.com'            # 发件人邮箱账户
receivers = ['rec@tespera.com']        # 收件人邮箱账户

subject = 'Python SMTP Email test'
message['Subject'] = Header(subject, 'utf-8')
 
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
message = MIMEText('Python Email test...', 'plain', 'utf-8')
message['From'] = Header("www.tespera.com", 'utf-8')       # 发送者
message['To'] =  Header(" Tespera", 'utf-8')            # 接收者
 
try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string()) 
    print("Send Mail OK !")
except smtplib.SMTPException:
    print("Send Mail Failed !")

在我们自己的服务器上执行上面的实例还需要你本机安装支持 SMTP 的服务,如:sendmail。

在CentOS下,sendmail 一般默认是随操作系统一起安装的。如果安装系统时没有安装 sendmail 服务,手动安装 sendmail 也很简单,依次执行下面两个指令:

yum install -y sendmail 
yum install -y sendmail-cf

安装完成之后,进行 senmail 的 SMTP 认证配置,首先需要确认 saslauthd 服务是否安装或启动。

yum install -y saslauthd
service saslauthd start
vi /etc/mail/sendmail.mc
dnl TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl 
dnl define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl

将上面两行行首的 dnl 去掉。在 sendmail 文件中,dnl 表示该行为注释行,是无效的。

sendmail 的配置十分复杂,它的配置文件是 sendmail.cf,位于 /etc/mail 目录下。

由于 sendmail.cf 的语法深奥难懂,很少有人会直接去修改该文件来对 sendmail 服务器进行配置。可见,这程序不是一般人写的。

我们一般通过 m4 宏处理程序来生成所需的 sendmail.cf 文件。创建的过程中还需要一个模板文件,系统默认在 /etc/mail 目录下有一个 sendmail.mc 模板文件。

m4 工具在 sendmail-cf 包中。如果系统无法识别 m4 命令,说明第一步的 sendmail-cf 软件包没有安装成功。

现在我们利用模板文件 sendmail.mc 来生成 sendmail 的配置文件 sendmail.cf:

m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf

重启 sendmail 使配置文件生效(重启非常的慢,需要耐心等待几分钟)

service sendmail restart

至此,sendmail 配置完毕。

现在将之前的实例保存成 sendmail.py 文件,修改发送和接收邮件的账户,然后运行:

python3 sendmail.py

如果系统还没有安装 Python3,请看我的这篇博客:《纯 Shell 脚本实现 CentOS 7 一键安装 Python3 及 pip3 并与 Python2 共存

执行之后,会在你的邮箱中(一般在垃圾箱里)看到一封标题为“Python SMTP Email test” 的新邮件,邮件内容为:Python Email test...。

可见,用 Python 和 sendmail 的配合是可以实现邮件的发送的。那么接下来我们就利用第三方的 SMTP 服务来实现邮件发送。

这里我写好了一个脚本,采用腾讯的 SMTP 邮件服务

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# Author:Tespera
# Blog: https://www.tespera.com/

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

## 邮件配置信息 ##

# 发件人邮箱账号
Email_From="test@domain.com"  
# 发件人邮箱密码 (填写客户端授权码,账户密码无效)
Email_Passwd="xxxxxxxxxxxxxxxx"
# 收件人邮箱账号 (发件人和收件人可以是同一个账号)
Email_To="user@domain.com"      
# 邮件标题,可自定义
Title="Notice : Blog Backup Successfully !"
# 邮件正文,可自定义
Message="Blog Backup Successfully !"

## 邮件配置信息 End ##

## 以下内容无需修改 ##
def mail():
    ret=True
    try:     
        msg=MIMEText(Message,'plain','utf-8') 
        msg['From']=formataddr(["root",Email_From])             # 发件人邮箱昵称、发件人邮箱账号
        msg['To']=formataddr(["me",Email_To])                   # 收件人邮箱昵称、收件人邮箱账号
        msg['Subject']= Title                                   # 邮件的主题,也可以说是标题
        server=smtplib.SMTP_SSL("smtp.qq.com", 465)             # 发件人邮箱中的SMTP服务器,默认端口是465
        server.login(Email_From, Email_Passwd)                  # 发件人邮箱账号、邮箱密码,用于模拟登陆
        server.sendmail(Email_From,[Email_To,],msg.as_string()) # 发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()  # 发送成功后关闭
    except Exception:  # 如果 try 中的语句没有执行,则会执行下面的 ret=False
        ret=False
    return ret

ret=mail()
if ret:  
    print("Send Mail OK !")
else:
    print("Send Mail Failed !")

将上面的代码保存为 sendmail.py 文件,修改邮件配置信息即可运行。现在邮件已经不在垃圾箱里了,在正常的收件箱里哦。

注意:既然采用了腾讯的 SMTP 服务,账号就只能填写 QQ 邮箱,如果想用网易的 SMTP 服务,请修改

server=smtplib.SMTP_SSL("smtp.qq.com", 465)

server=smtplib.SMTP_SSL("smtp.163.com", 465) # 如果 465 端口不行,请用 994

其余类同。

现在我们要实现每天在网站备份成功后自动发送邮件告知我们备份结果,所以还请先看我的这篇博客:《Shell 脚本实现网站及数据库定时自动备份》,做好自动备份的 Shell 脚本,然后在脚本最后添加如下命令:

# 发送邮件
echo -e "\nStart Send Mail ..."
python3 $(dirname $0)/sendmail.py

将 sendmail.py 文件和 执行备份的 Shell 脚本放在同一个目录下,现在执行 AutoBackupWebsite.sh 脚本,备份结束之后会收到一封邮件通知备份结果。

赶快试试吧!Enjoy !

文章标签: Python, Sendmail
点此生成 >> 文章海报


上一篇 : 如何在关闭ssh连接的情况下,让程序继续运行?
下一篇 : Shell 脚本实现网站及数据库定时自动备份
留言