python发送邮件
本文主要是针对统计数据库中数据,并将数据存在Excel中,最后通过邮件将Excel发送给指定用户;直接上代码。
一、日志配置文件 Logger.conf
############################################
[loggers]
keys = root,example01,example02
[logger_root]
level = DEBUG
handlers = hand01,hand02
[logger_example01]
handlers = hand01,hand02
qualname = example01
propagate = 0
[logger_example02]
handlers = hand01,hand03
qualname = example02
propagate = 0
############################################
[handlers]
keys = hand01,hand02,hand03
[handler_hand01]
class = StreamHandler
level = DEBUG
formatter = form01
args = (sys.stderr,)
[handler_hand02]
class = FileHandler
lever = DEBUG
formatter = form01
args = ('./Result_count.log','a')
[handler_hand03]
class = handlers.RotatingFileHandler
lever = INFO
formatter = form01
args = ('./Result_count.log','a',10*1024*1024,5)
############################################
[formatters]
keys = form01,form02
[formatter_form01]
format = %(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt = %Y-%m-%d %H:%M:%S
[formatter_form02]
format = %(name) -12s: %(levelname) -8s %(message)s
datefmt = %Y-$m-%d %H:%M:%S
二、读取配置文件的程序:Log.py
#!/usr/bin/python
#encoding=utf-8
import logging.config
logging.config.fileConfig("Logger.conf")
def debug(message):
logging.debug(message)
def warning(message):
logging.warning(message)
def info(message):
logging.info(message)
三、连接数据库并将统计结果存成Excel
#!/usr/bin/python
# -*- coding:utf-8 -*-
'''
方法:通过pymsql模块连接mysql数据库,然后通过游标cursor查询SQL语句将结果存储在Excel文件中,其中Excel的生成使用xlwt实现的。
作者:范先生
时间:2018年4月
'''
import pymysql
import xlwt
import datetime
from Log import *
def Select_data():
conn = pymysql.connect(host='x.x.x.x', port=xxx, user='root', passwd='PxxxxxxxSH', db='xx', charset='utf8')
logging.info(u"#连接mysql数据库成功!")
logging.info(u"#使用cursor()方法获取操作游标;")
cursor = conn.cursor()
logging.info(u"#使用execute方法执行SQL语句,并将统计结果存储在effect_row变量中;")
today = datetime.datetime.today() #获取今天的日期.
yesterday = today - datetime.timedelta(days=1) #获取昨天的日期.
tomorrow = today + datetime.timedelta(days=1) #获取明天的日期.
today_a = datetime.datetime(today.year, today.month, today.day, 0, 0, 0) #获取今天凌晨的时间.
yesterday_b = datetime.datetime(yesterday.year, yesterday.month, yesterday.day, 0, 0, 0)#获取昨天凌晨的时间.
tomorrow_c = datetime.datetime(tomorrow.year, tomorrow.month, tomorrow.day, 0, 0, 0) #获取明天凌晨的时间.
#格式化时间输出,用于给Excel起名时使用。
sheet_time = datetime.datetime.now()
book_mark = sheet_time.strftime('%Y%m%d')
#将统计结果存储在变量effect_row中.
effect_row = cursor.execute("select a.username,a.mac,count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)),count(if(b.ntype='xx',true,null)) from nctermnetlog_if_%s a,ncsnettype b where a.nettype=b.ntype and stime>unix_timestamp('%s') and stime<unix_timestamp('%s') group by a.username"%(book_mark[0:6],str(yesterday_b),str(today_a)))
#获取所有的记录列表,也就是总行数.
#print effect_row #打印总行数.
#获取统计信息,并将结果存在row_3中.
row_3 = cursor.fetchall()
#print row_3 #打印统计内容.
#获取上述SQL语句中的检索条件名称(将要成为Excel第一行的表头)。
fields = cursor.description
logging.info(u"#依次做提交请求和关闭断开操作;")
conn.commit()
cursor.close()
conn.close()
return row_3,book_mark,fields
def WritToExcel():
Data = Select_data()
logging.info(u"#将字段名写入到EXCEL表头;")
workbook = xlwt.Workbook(encoding='utf-8')
#创建Excel中的一个sheet,并命名且为可重写状态。
sheet = workbook.add_sheet('result_count',cell_overwrite_ok=True)
#构造一个列表VnameList,用于将上述表头重命名,一定要一一对应。
VnameList = [u"用户名","MAC",u"微信ID","QQ",u"新浪微博",u"腾讯微博",u"腾讯视频",u"京东商城",u"淘宝",u"今日头条",u"美团"]
logging.info(u"#将VnameList中的虚拟身份依次填入Excel中;")
for field in range(0,len(VnameList)):
sheet.write(0,field,VnameList[field].encode("utf-8"))
#根据横纵坐标依次录入查询到的信息值。
row = 1
col = 0
for row in range(1,len(Data[0])+1):
for col in range(0,len(Data[2])):
sheet.write(row,col,u'%s'%Data[0][row-1][col])
logging.info(u"#将Excel文件保存下来;")
logging.info(u"#保存成功!!!\n")
workbook.save('./Count_result%s.xls'%Data[1].encode("utf-8"))
if __name__=="__main__":
WritToExcel()
四、邮件发送程序
#!/usr/bin/python
# -*- coding:utf-8 -*-
'''
方法:通过SNMP协议的163邮箱登录成功后,读取指定位置的附件,并将附件发送给指定接收人员。
作者:范先生
时间:2018年4月
'''
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.header import Header
import time
import datetime
from Log import *
import ConMySqlOut
ConMySqlOut.WritToExcel()
time.sleep(5)
# print "*"*60
def SendMail():
smtpserver = 'smtp.163.com'
username = 'dpexxxx@163.com'
password='xxxxxx' #授权码
sender='dpeng_fan@163.com'
logging.info(u"# 登录邮箱服务器成功;")
receiver=['923xxxx@qq.com','fanxxx@pxxxxx.com']
#生成今天的日期,格式化输出为年月日;生成昨天的日期,格式化输出为年月日
sheet_time = datetime.datetime.now()
book_mark = sheet_time.strftime('%Y%m%d')
today = datetime.datetime.today()
yesterday = today - datetime.timedelta(days=1)
yesterday_b = datetime.datetime(yesterday.year, yesterday.month, yesterday.day, 0, 0, 0)
book_mark1 = yesterday_b.strftime('%Y%m%d')
logging.info(u"#构造邮件的主题、发件人和收件人信息;")
subject ="%s虚拟身份统计结果,请注意查收!"%book_mark1
msg = MIMEMultipart('mixed')
msg['Subject'] = subject
msg['From'] ="范先生的163邮箱<dpeng_fan@163.com>"
msg['To'] = ";".join(receiver)
logging.info(u"#构造附件;")
sendfile=open('./Count_result%s.xls'%book_mark,'rb').read()
text_att = MIMEText(sendfile, 'base64', 'utf-8')
text_att["Content-Type"] = 'application/octet-stream'
text_att.add_header('Content-Disposition', 'attachment', filename='Count_result%s.xls'%book_mark1)
msg.attach(text_att)
logging.info(u"#构造成功,准备发送邮件!")
#===============================================================================================================
# 发送邮件;考虑到服务器会将邮件作为垃圾邮件处理,导致邮件发送失败,返回554,于是做了死循环,直到发送成功。
#===============================================================================================================
try:
Failure_count =0
while True:
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
#print "Send Success!!!"
logging.warning(u"#邮件发送成功!!!")
break
except Exception as err:
print 'Sending Mail Failed:{0}'.format(err)
logging.warning('Sending Mail Failed:{0}'.format(err))
Failure_count+=1
info('Send Failure counts are %s'%Failure_count)
# continue
finally:
smtp.quit()
if __name__ == "__main__":
SendMail()