《运维--PlayBook》更新中.......!请访问: https://ops.cnmysql.com
python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。
smtp协议的基本命令包括:
HELO 向服务器标识用户身份
MAIL 初始化邮件传输 mail from:
RCPT 标识单个的邮件接收人;常在MAIL命令后面,可有多个rcpt to:
DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束
VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作,服务器应响应OK
QUIT 结束会话
RSET 重置会话,当前传输被取消
MAIL FROM 指定发送者地址
RCPT TO 指明的接收者地址
Python创建 SMTP 对象:
python smtp对象使用sendmail方法发送邮件的语法如下:
一个发送邮件的小例子:
用python发送HTML格式的邮件:
Python 发送带附件的邮件:
Python 发送带图片的HTML邮件:
Python 发送包含多种元素的邮件
smtp协议的基本命令包括:
HELO 向服务器标识用户身份
MAIL 初始化邮件传输 mail from:
RCPT 标识单个的邮件接收人;常在MAIL命令后面,可有多个rcpt to:
DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束
VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作,服务器应响应OK
QUIT 结束会话
RSET 重置会话,当前传输被取消
MAIL FROM 指定发送者地址
RCPT TO 指明的接收者地址
Python创建 SMTP 对象:
import smtplib
SMTPObj = smtplib.SMTP( [host [,port [,local_hostname]]] )
参数说明:
host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如:i-it.info,这个是可选参数。
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下SMTP端口号为25。
local_hostname: 如果SMTP在你的本机上,你只需要指定服务器地址为 localhost 即可。
SMTPObj = smtplib.SMTP( [host [,port [,local_hostname]]] )
参数说明:
host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如:i-it.info,这个是可选参数。
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下SMTP端口号为25。
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协议中定义的格式。
参数说明:
from_addr: 邮件发送者地址。
to_addrs: 字符串列表,邮件发送地址。
msg: 发送消息
这里要注意一下第三个参数,msg是字符串,表示邮件。邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意msg的格式。这个格式就是smtp协议中定义的格式。
一个发送邮件的小例子:
import smtplib
send = '18717776124@163.com'
receivers = ['itchenyi@gmail.com']
UserPass = ['18717776124@163.com','%password%']
message = """From: From Person <18717776124@163.com>
TO: To Person <itchenyi@gmail.com>
Subject: SMTP e-mail test
This is a test email message.
"""
try:
SMTPObj = smtplib.SMTP("smtp.163.com","25")
SMTPObj.login('%s'%UserPass[0],"%s"%UserPass[1])
SMTPObj.sendmail(send,receivers,message)
SMTPObj.quit()
print "Successfully sent email"
except:
print "Error: unable to send email"
send = '18717776124@163.com'
receivers = ['itchenyi@gmail.com']
UserPass = ['18717776124@163.com','%password%']
message = """From: From Person <18717776124@163.com>
TO: To Person <itchenyi@gmail.com>
Subject: SMTP e-mail test
This is a test email message.
"""
try:
SMTPObj = smtplib.SMTP("smtp.163.com","25")
SMTPObj.login('%s'%UserPass[0],"%s"%UserPass[1])
SMTPObj.sendmail(send,receivers,message)
SMTPObj.quit()
print "Successfully sent email"
except:
print "Error: unable to send email"
用python发送HTML格式的邮件:
###Python发送HTML格式的邮件与发送纯文本消息的邮件不同之处就是将MIMEText中_subtype设置为html###
import smtplib
from email.mime.text import MIMEText
mailto_list = ["itchenyi@gmail.com"]
mail_host = "smtp.163.com"
##smtp server##
mail_user = "18717776124"
##username##
mail_pass = "%password%"
##password##
mail_postfix = "163.com"
##后缀##
def send_email(to_list,sub,content):
###定义收件人列表,主题,邮件内容###
me = "hello"+"<"+mail_user+"@"+mail_postfix+">"
###hello信息###
msg = MIMEText(content,_subtype='html',_charset='utf8')
###创建实例,设置为html格式##
msg['Subject'] = sub
###主题###
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
s = smtplib.SMTP()
s.connect(mail_host)
s.login(mail_user,mail_pass)
s.sendmail(me,to_list,msg.as_string())
s.close()
return True
except Exception,e:
print str(e)
return False
if __name__ == '__main__':
if send_email(mailto_list,"hello","<a href="http://www.ipython.me">IT辰逸</a>"):
print "send Successfully"
else:
print "send Error"
import smtplib
from email.mime.text import MIMEText
mailto_list = ["itchenyi@gmail.com"]
mail_host = "smtp.163.com"
##smtp server##
mail_user = "18717776124"
##username##
mail_pass = "%password%"
##password##
mail_postfix = "163.com"
##后缀##
def send_email(to_list,sub,content):
###定义收件人列表,主题,邮件内容###
me = "hello"+"<"+mail_user+"@"+mail_postfix+">"
###hello信息###
msg = MIMEText(content,_subtype='html',_charset='utf8')
###创建实例,设置为html格式##
msg['Subject'] = sub
###主题###
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
s = smtplib.SMTP()
s.connect(mail_host)
s.login(mail_user,mail_pass)
s.sendmail(me,to_list,msg.as_string())
s.close()
return True
except Exception,e:
print str(e)
return False
if __name__ == '__main__':
if send_email(mailto_list,"hello","<a href="http://www.ipython.me">IT辰逸</a>"):
print "send Successfully"
else:
print "send Error"
Python 发送带附件的邮件:
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
##创建一个带附件的实例##
msg = MIMEMultipart()
##构造附件##
att_one = MIMEText(open('D:\\testfile','rb').read(),'base64','utf8')
att_one["Content-Type"] = 'application/octet-stream'
att_one["Content-Disposition"] = 'attachment; filename="testfile"'
msg.attach(att_one)
##构造附件##
att_two = MIMEText(open('D:\\testfile.zip','rb').read(),'base64','utf8')
att_two["Content-Type"] = 'applecation/octet-stream'
att_two["Content-Disposition"] = 'attachment; filename="testfile.zip"'
msg.attach(att_two)
##邮件头##
msg['to'] = "itchenyi@gmail.com"
msg['from'] = '18717776124@163.com'
msg['subject'] = 'test email'
##发送邮件##
try:
server = smtplib.SMTP()
server.connect('smtp.163.com')
server.login('18717776124@163.com','%password%')
server.sendmail(msg['from'],msg['to'],msg.as_string())
server.quit()
print "send Successfully"
except Exception,e:
print str(e)
from email.mime.multipart import MIMEMultipart
import smtplib
##创建一个带附件的实例##
msg = MIMEMultipart()
##构造附件##
att_one = MIMEText(open('D:\\testfile','rb').read(),'base64','utf8')
att_one["Content-Type"] = 'application/octet-stream'
att_one["Content-Disposition"] = 'attachment; filename="testfile"'
msg.attach(att_one)
##构造附件##
att_two = MIMEText(open('D:\\testfile.zip','rb').read(),'base64','utf8')
att_two["Content-Type"] = 'applecation/octet-stream'
att_two["Content-Disposition"] = 'attachment; filename="testfile.zip"'
msg.attach(att_two)
##邮件头##
msg['to'] = "itchenyi@gmail.com"
msg['from'] = '18717776124@163.com'
msg['subject'] = 'test email'
##发送邮件##
try:
server = smtplib.SMTP()
server.connect('smtp.163.com')
server.login('18717776124@163.com','%password%')
server.sendmail(msg['from'],msg['to'],msg.as_string())
server.quit()
print "send Successfully"
except Exception,e:
print str(e)
Python 发送带图片的HTML邮件:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
send = '18717776124@163.com'
receiver = 'itchenyi@gmail.com'
subject = 'email test'
username = '18717776124@163.com'
password = '%password%'
msg = MIMEMultipart('related')
msg['subject'] = 'test email'
msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>good!','html','utf-8')
msg.attach(msgText)
fp = open('D:\\i-it.jpg','rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', '<image1>')
msg.attach(msgImage)
try:
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
smtp.login(username, password)
smtp.sendmail(send, receiver, msg.as_string())
smtp.quit()
print "send Successfully"
except Exception,e:
print str(e)
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
send = '18717776124@163.com'
receiver = 'itchenyi@gmail.com'
subject = 'email test'
username = '18717776124@163.com'
password = '%password%'
msg = MIMEMultipart('related')
msg['subject'] = 'test email'
msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>good!','html','utf-8')
msg.attach(msgText)
fp = open('D:\\i-it.jpg','rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', '<image1>')
msg.attach(msgImage)
try:
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
smtp.login(username, password)
smtp.sendmail(send, receiver, msg.as_string())
smtp.quit()
print "send Successfully"
except Exception,e:
print str(e)
Python 发送包含多种元素的邮件
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
send = '18717776124@163.com'
receiver = 'itchenyi@gmail.com'
subject = 'python email test'
smtpserver = 'smtp.163.com'
username = '18717776124@163.com'
password = '%password%'
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
text = "Hi!\nHow are you?"
html = """
Hi!
How are you?
"""
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
msg.attach(part1)
msg.attach(part2)
att = MIMEText(open('d:\\i-it.jpg', 'rb').read(), 'base64', 'utf-8')
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename="iit.jpg"'
msg.attach(att)
try:
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
smtp.login(username, password)
smtp.sendmail(send, receiver, msg.as_string())
smtp.quit()
print "send Successfully"
except Exception,e:
print str(e)
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
send = '18717776124@163.com'
receiver = 'itchenyi@gmail.com'
subject = 'python email test'
smtpserver = 'smtp.163.com'
username = '18717776124@163.com'
password = '%password%'
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
text = "Hi!\nHow are you?"
html = """
Hi!
How are you?
"""
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
msg.attach(part1)
msg.attach(part2)
att = MIMEText(open('d:\\i-it.jpg', 'rb').read(), 'base64', 'utf-8')
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename="iit.jpg"'
msg.attach(att)
try:
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
smtp.login(username, password)
smtp.sendmail(send, receiver, msg.as_string())
smtp.quit()
print "send Successfully"
except Exception,e:
print str(e)
最近接到一个需求…自动发布SVN代码…收到的代码原型大部分就是依靠subprocess 来实现的,册那…有一段时间没有用这个模块了,这个模块的能力不差,不过我已经习惯了 commands … 再复杂点有fabric也够用啦…既然要了解代码,我不得不看看subprocess ,借此机会 记录下…
subprocess.Popen(类):
args参数。可以是一个字符串,可以是一个包含程序参数的列表。要执行的程序一般就是这个列表的第一项,或者是字符串本身。
示例:
subprocess.PIPE用于Popen的stdin 、stdout 和stderr 3个参数
subprocess.STDOUT用于Popen的stderr参数的输出值
subprocess.Popen(类):
class subprocess.Popen( args,
bufsize=0,
executable=None,
stdin=None,
stdout=None,
stderr=None,
preexec_fn=None,
close_fds=False,
shell=False,
cwd=None,
env=None,
universal_newlines=False,
startupinfo=None,
creationflags=0)
#########################参数########################
args 字符串或者列表
bufsize 0 无缓冲,1 行缓冲,其他正值 缓冲区大小,负值 采用默认系统缓冲(一般是全缓冲)
executable args字符串或列表第一项表示程序名
stdin,stdout,stderr None 没有任何重定向,继承父进程,PIPE 创建管道,文件对象,文件描述符(整数),stderr 还可以设置为 STDOUT
preexec_fn 只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用。
close_fds 如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管 道。不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell 如果为真(unix下相当于args前面添加了 "/bin/sh" "-c"|window下,相当于添加"cmd.exe /c")
cwd 设置工作目录
env 设置环境变量
universal_newlines 各种换行符统一处理成 '\n
startupinfo window下传递给CreateProcess的结构体
creationflags windows下,传递CREATE_NEW_CONSOLE创建自己的控制台窗口
bufsize=0,
executable=None,
stdin=None,
stdout=None,
stderr=None,
preexec_fn=None,
close_fds=False,
shell=False,
cwd=None,
env=None,
universal_newlines=False,
startupinfo=None,
creationflags=0)
#########################参数########################
args 字符串或者列表
bufsize 0 无缓冲,1 行缓冲,其他正值 缓冲区大小,负值 采用默认系统缓冲(一般是全缓冲)
executable args字符串或列表第一项表示程序名
stdin,stdout,stderr None 没有任何重定向,继承父进程,PIPE 创建管道,文件对象,文件描述符(整数),stderr 还可以设置为 STDOUT
preexec_fn 只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用。
close_fds 如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管 道。不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell 如果为真(unix下相当于args前面添加了 "/bin/sh" "-c"|window下,相当于添加"cmd.exe /c")
cwd 设置工作目录
env 设置环境变量
universal_newlines 各种换行符统一处理成 '\n
startupinfo window下传递给CreateProcess的结构体
creationflags windows下,传递CREATE_NEW_CONSOLE创建自己的控制台窗口
args参数。可以是一个字符串,可以是一个包含程序参数的列表。要执行的程序一般就是这个列表的第一项,或者是字符串本身。
###可以正常工作###
>>> subprocess.Popen(["cat","i-it"])
###不可以正常工作,如果是一整个字符串,则必须是程序的路径才行(因为Unix的API函数是Exec ,接受的是字符串列表)###
>>> subprocess.Popen(["cat i-it"])
###但如果shell = True 就可以工作啦###
>>> subprocess.Popen("cat /root/i-it",shell=True)
----这个相当于----(bash)
>>> subprocess.Popen(["/bin/sh", "-c", "cat i-it"])
>>> subprocess.Popen(["cat","i-it"])
###不可以正常工作,如果是一整个字符串,则必须是程序的路径才行(因为Unix的API函数是Exec ,接受的是字符串列表)###
>>> subprocess.Popen(["cat i-it"])
###但如果shell = True 就可以工作啦###
>>> subprocess.Popen("cat /root/i-it",shell=True)
----这个相当于----(bash)
>>> subprocess.Popen(["/bin/sh", "-c", "cat i-it"])
示例:
import subprocess
def runCommandWithOutput(cmd,stdinstr = ''):
p=subprocess.Popen(cmd, shell=True, universal_newlines=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#p.stdin.write(stdinstr)
stdoutdata, stderrdata = p.communicate(stdinstr)
#p.stdin.close()
return p.returncode, stdoutdata, stderrdata
>>> get = runCommandWithOutput("who")
>>> print get
(0, 'root tty1 2014-06-24 05:51\nroot pts/0 2014-06-24 05:51 (1.1.1.2)\n', None)
def runCommandWithOutput(cmd,stdinstr = ''):
p=subprocess.Popen(cmd, shell=True, universal_newlines=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#p.stdin.write(stdinstr)
stdoutdata, stderrdata = p.communicate(stdinstr)
#p.stdin.close()
return p.returncode, stdoutdata, stderrdata
>>> get = runCommandWithOutput("who")
>>> print get
(0, 'root tty1 2014-06-24 05:51\nroot pts/0 2014-06-24 05:51 (1.1.1.2)\n', None)
subprocess.PIPE用于Popen的stdin 、stdout 和stderr 3个参数
subprocess.STDOUT用于Popen的stderr参数的输出值
###很清晰了###
>>> test = subprocess.Popen("who",shell=True,stdout=subprocess.PIPE)
>>> test.stdout.readlines()
['root tty1 2014-06-24 05:51\n', 'root pts/0 2014-06-24 05:51 (1.1.1.2)\n']
Popen.send_signal(signal)
给子进程发送signal信号。
注意:windows下目前只支持发送SIGTERM,等效于下面的terminate() 。
Popen.terminate()
停止子进程。Posix下是发送SIGTERM信号。windows下是调用TerminateProcess()这个API。
Popen.kill()
杀死子进程。Posix下是发送SIGKILL信号。windows下和terminate() 无异。
Popen.stdin
如果stdin 参数是PIPE,此属性就是一个文件对象,否则为None 。
Popen.stdout
如果stdout参数是PIPE,此属性就是一个文件对象,否则为None 。
Popen.stderr
如果stderr 参数是PIPE,此属性就是一个文件对象,否则为None 。
Popen.pid
子进程的进程号。注意,如果shell 参数为True,这属性指的是子shell的进程号。
>>> test.pid
3367
Popen.returncode
子程序的返回值,由poll()或者wait()设置,间接地也由communicate()设置。
如果为None,表示子进程还没终止。
如果为负数-N的话,表示子进程被N号信号终止。(仅限*nux)
>>> test = subprocess.Popen("who",shell=True,stdout=subprocess.PIPE)
>>> test.stdout.readlines()
['root tty1 2014-06-24 05:51\n', 'root pts/0 2014-06-24 05:51 (1.1.1.2)\n']
Popen.send_signal(signal)
给子进程发送signal信号。
注意:windows下目前只支持发送SIGTERM,等效于下面的terminate() 。
Popen.terminate()
停止子进程。Posix下是发送SIGTERM信号。windows下是调用TerminateProcess()这个API。
Popen.kill()
杀死子进程。Posix下是发送SIGKILL信号。windows下和terminate() 无异。
Popen.stdin
如果stdin 参数是PIPE,此属性就是一个文件对象,否则为None 。
Popen.stdout
如果stdout参数是PIPE,此属性就是一个文件对象,否则为None 。
Popen.stderr
如果stderr 参数是PIPE,此属性就是一个文件对象,否则为None 。
Popen.pid
子进程的进程号。注意,如果shell 参数为True,这属性指的是子shell的进程号。
>>> test.pid
3367
Popen.returncode
子程序的返回值,由poll()或者wait()设置,间接地也由communicate()设置。
如果为None,表示子进程还没终止。
如果为负数-N的话,表示子进程被N号信号终止。(仅限*nux)
在python中,Main可以说是程序执行的起点,但也不全是,Python 使用缩进组织整个代码结构,所有没有缩进的代码(非函数定义和类定义),都会在载入时自动执行,这些代码,可以认为是Python的main函数。
如下:
###这段代码的主要作用主要是让该python文件既可以独立运行,也可以当做模块导入到其他文件###
###当导入到其他的脚本文件的时候,此时__name__的名字其实是导入模块的名字,不是'__main__', main代码里面的就不执行了###
if __name__ == '__main__':
print "test __name__"
示例:
>>> def test():
... print("Test function.")
... print("main")
...
>>> if __name__ == '__main__':
... test()
输出如下:
...
Test function.
main
当作为模块被导入时:
##当你直接执行.py时,__name__是__main__,当作为模块被导入时,则是模块的名字....##
>>> import example
>>> example.test
>>> example.test()
Test function.
>>> example.__name__
'example'
如下:
###这段代码的主要作用主要是让该python文件既可以独立运行,也可以当做模块导入到其他文件###
###当导入到其他的脚本文件的时候,此时__name__的名字其实是导入模块的名字,不是'__main__', main代码里面的就不执行了###
if __name__ == '__main__':
print "test __name__"
示例:
>>> def test():
... print("Test function.")
... print("main")
...
>>> if __name__ == '__main__':
... test()
输出如下:
...
Test function.
main
当作为模块被导入时:
##当你直接执行.py时,__name__是__main__,当作为模块被导入时,则是模块的名字....##
>>> import example
>>> example.test
>>> example.test()
Test function.
>>> example.__name__
'example'