zoukankan      html  css  js  c++  java
  • 基于邮件系统的远程实时监控系统的实现 Python版

    人生苦短,我用Python~ 界内的Python宣传标语,对Python而言,这是种标榜,实际上,Python确实是当下最好用的开发语言之一。

    在相继学习了C++/C#/Java之后,接触Python,最一开始突然一片茫然,似乎是进入了新世界,所有C家族的语法,在这里都或多或少地发生了改变,方法没有大括号,喜闻乐见的格式。定义变量不需要声明,时间长了,竟爱上了这个简介明了,高效快捷的语言,当然,也是当下开发语言界内的宠儿,不可否认,Python是当下最流行的开发语言了。

    【前言】

    本文拟使用Python开发语言实现在任何能链接上互联网的地方,远程启动在其他地方部署的监控系统,并且实时地进行图像连拍,将实时图像以邮件形式反馈到手机邮箱,达到远程实时监控的目的。

    【实现功能】

    这篇文章将要介绍的主要内容如下:

    1、远程发送监控命令

    2、监控系统做出相应,进行图像连拍(或者是录制一段视频)

    3、监控系统将处理结果以邮件形式发送到移动端

    【实现思路】

    远程向某邮箱服务器发送一封邮件,监控系统循环检测此邮箱最新接受的邮件,通过获取并分析邮件的信息确定是否需要执行监控功能操作。如果需要,做出响应,拍照并且将拍照结果反馈回邮件发送方。

    【所需技术】

    1、Python语言的熟练掌握,Python版本2.7

    2、利用Python语言,实现SMTP协议以及POP3协议。已达到发送邮件和接收邮件的功能。

    3、正则表达式的简单使用

    4、OpenCV 图像处理,图像识别,跨平台开发库的使用

    5、邮箱服务器SMTP,POP3协议的开通

    【实现过程】

    1、实现Python发送接收邮件代码,最后封装成Email_Helper_DG类,便于后续调用,当然本文的Python_Helper_DG还没有达到更高层次的封装,毕竟要发送图片的,适当做了一些对本系统的适应。

    邮件发送接受的Email_Helper_DG代码如下:

      1 # -*- coding: UTF-8 -*-
      2 import os
      3 import poplib
      4 import smtplib
      5 from email.mime.application import MIMEApplication
      6 from email.mime.audio import MIMEAudio
      7 from email.mime.image import MIMEImage
      8 from email.mime.multipart import MIMEMultipart
      9 from email.mime.text import MIMEText
     10 from email.utils import formataddr
     11 
     12 
     13 class Mail_Helper_DG:
     14     my_smtp_server = 'smtp.sina.com'  # smtp 邮件服务地址
     15     my_pop3_server = 'pop.sina.com'  # pop3 邮件服务地址
     16     mail_type = 'html'  # 发送的邮件的格式,HTML或者Plain
     17     my_account = '******@example.com'  # 发件人邮箱账号
     18     my_pwd = '******'  # 发件人邮箱密码
     19     toAddressArray = ['xxxxx@example.com', ]  # 收件人的邮箱,可发送给多人
     20 
     21     def __init__(self):
     22         pass
     23 
     24     # 发送邮件
     25     def SendMail(self, toAddressArray, senderName, subject, content):
     26         try:
     27             server = smtplib.SMTP(self.my_smtp_server, 25)  # 发件人邮箱中的SMTP服务器,端口是25
     28 
     29             try:
     30                 msg = MIMEText(content, self.mail_type, 'utf-8')
     31                 msg['From'] = formataddr([senderName, self.my_account])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
     32                 # msg['To'] = formataddr(["FK", my_account])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
     33                 msg['Subject'] = subject  # 邮件的主题,也可以说是标题
     34 
     35                 server.login(self.my_account, self.my_pwd)  # 括号中对应的是发件人邮箱账号、邮箱密码
     36                 server.sendmail(self.my_account, toAddressArray, msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
     37             except Exception:
     38                 print(Exception)
     39                 return False
     40             finally:
     41                 server.quit()  # 关闭连接
     42             return True
     43         except Exception:
     44             print(Exception)
     45             return False
     46 
     47     # 发送邮件带附件
     48     def SendMailAttachment(self, toAddressArray, senderName, subject, content, attachment_path):
     49         try:
     50             server = smtplib.SMTP(self.my_smtp_server, 25)  # 发件人邮箱中的SMTP服务器,端口是25
     51 
     52             try:
     53                 server.login(self.my_account, self.my_pwd)  # 括号中对应的是发件人邮箱账号、邮箱密码
     54 
     55                 msg = MIMEMultipart()  # create MIMEMultipart
     56                 msg['From'] = formataddr([senderName, self.my_account])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
     57                 # msg['To'] = formataddr(["FK", my_account])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
     58                 msg['Subject'] = subject  # 邮件的主题,也可以说是标题
     59                 content2 = MIMEText(content,
     60                                     _charset='utf-8')  # add email content  ,coding is gbk, becasue chinese exist
     61                 msg.attach(content2)
     62                 for attachment_name in os.listdir(attachment_path):
     63                     attachment_file = os.path.join(attachment_path, attachment_name)
     64 
     65                     with open(attachment_file, 'rb') as attachment:
     66                         if 'application' == 'text':
     67                             attachment = MIMEText(attachment.read(), _subtype='octet-stream', _charset='GB2312')
     68                         elif 'application' == 'image':
     69                             attachment = MIMEImage(attachment.read(), _subtype='octet-stream')
     70                         elif 'application' == 'audio':
     71                             attachment = MIMEAudio(attachment.read(), _subtype='octet-stream')
     72                         else:
     73                             attachment = MIMEApplication(attachment.read(), _subtype='octet-stream')
     74 
     75                     attachment.add_header('Content-Disposition', 'attachment', filename=('gbk', '', attachment_name))
     76                     # make sure "attachment_name is chinese" right
     77                     msg.attach(attachment)
     78 
     79                 server.sendmail(self.my_account, toAddressArray, msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
     80             except Exception:
     81                 print(Exception)
     82                 return False
     83             finally:
     84                 server.quit()  # 关闭连接
     85             return True
     86         except Exception:
     87             print(Exception)
     88             return
     89 
     90     # 接收邮件
     91     def ReceiveMail(self):
     92         # 创建一个pop3对象,这个时候实际上已经连接上服务器了
     93         pp = poplib.POP3(self.my_pop3_server)
     94         # 设置调试模式,可以看到与服务器的交互信息
     95         pp.set_debuglevel(1)
     96         # 向服务器发送用户名
     97         pp.user(self.my_account)
     98         # 向服务器发送密码
     99         pp.pass_(self.my_pwd)
    100         # 返回邮箱的状态,返回2元祖(消息的数量,消息的总字节)
    101         # msgCount, msgSize = pp.stat()
    102 
    103         ret = pp.list()
    104 
    105         mailBody = pp.retr(len(ret[1]))
    106         # 释放pp
    107         pp.quit()
    108 
    109         return mailBody

    2、主要业务逻辑代码,其中包含对POP3邮箱的实时监测,且对捕获到的命令进行分析判断,最后做出响应:

     1 # -*- coding: UTF-8 -*-
     2 import re
     3 import time
     4 import cv2
     5 
     6 from Email import Mail_Helper_DG
     7 
     8 toAddressArray = ['wd8622088@foxmail.com']  # 收件人的邮箱,可发送给多人
     9 
    10 content = """
    11 当前摄像头捕获的结果:
    12 """
    13 
    14 
    15 # 获取当前时间
    16 def getCurrentTime():
    17     return str(time.strftime('’%Y-%m-%d %X’', time.localtime(time.time())))
    18 
    19 
    20 # 程序启动标识
    21 print('QiXiao`s SHS Starting ...')
    22 # 初始化邮件发送类
    23 mail = Mail_Helper_DG()
    24 
    25 # 声明一个变量,来作为一个标记判断是否已经检测过当前这封邮件了
    26 last_receiveMailDate = ''
    27 # 输出显示当前扫描邮箱服务器的次数
    28 scan_index = 0
    29 # 设置一个循环检测邮箱的方法
    30 while True:
    31     time.sleep(10)  # 设置检测邮箱服务器的时间间隔
    32     print(getCurrentTime() + ' : scan item >>> ' + str(scan_index))
    33     scan_index += 1  # 扫描次数累加
    34     try:
    35         # 通过Pop3 获取到邮件的第一条
    36         mailBody = mail.ReceiveMail()
    37 
    38         # 解析第一条邮件,并得到发件人,主题,日期
    39         sender = re.search("X-Sender: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1)
    40         subject = re.search("Subject: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1)
    41         date = re.search("Date: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1)
    42 
    43         # 判断解析到的参数值
    44         if date != last_receiveMailDate:
    45             # 对发送方进行邮箱判断,否则任何人都可以发送命令,你懂得
    46             if sender == 'wd8622088@foxmail.com':
    47                 # 对命令进行分析
    48                 if subject.__contains__('qx_cmd:'):
    49                     cmd = subject.split(':')[1]
    50                     # 按cmd的命令来匹配要执行的操作:
    51                     # catch-camera 捕获摄像头的操作
    52                     if cmd == 'catch-camera':
    53                         # 载入图像,连续捕获数张图片,间隔三秒
    54                         video = cv2.VideoCapture(0)
    55                         time.sleep(3)
    56                         ret, img = video.read()
    57                         cv2.imwrite('files\\shoot_001.jpg', img)
    58 
    59                         time.sleep(3)
    60                         ret, img = video.read()
    61                         cv2.imwrite('files\\shoot_002.jpg', img)
    62 
    63                         time.sleep(3)
    64                         ret, img = video.read()
    65                         cv2.imwrite('files\\shoot_003.jpg', img)
    66 
    67                         video.release()  # 关闭摄像头
    68                         result = mail.SendMailAttachment(toAddressArray, "QiXiao",
    69                                                          "QiXiao`s SHS (QiXiao`s Smart Home System v1.0)", content,
    70                                                          "files")
    71                         if result is True:
    72                             print(getCurrentTime() + ' : send mail success !')
    73                         else:
    74                             print(getCurrentTime() + ' : send fail #')
    75 
    76                     # 让当前这条信息的日期赋值给标记变量,以便下次略过当前这条信息
    77                     last_receiveMailDate = date
    78     except Exception:
    79         print(getCurrentTime() + 'Error:' + Exception)

    至于代码逻辑的分析,代码内部已有适当的注释进行讲解,这里不再赘述,如有任何疑问,请留言,本人进行一一回复。

    【系统测试】

    首先我们启动我们的服务器,让代码跑起来。

    每隔一段时间,服务器就会自动请求一次POP3服务器,判断是否有新的命令输入。

    然后我们在任何地点进行邮件命令的发送:这里以Ios自带的Mail来进行邮件的发送(邮件客户端无所谓,微信里的也可以)

    我们首先要填写好要发送的邮箱地址,以及主题(这里是约定好的执行命令)

    填写好后,点击发送。

    可以看到在0:00发送了一条邮件,这就是我们刚才发送的邮件。然后打开收件箱,准备进行邮件的查收。

    我们可以看到,两分钟后,服务端以邮件形式返回监控的结果。打开邮箱进行查看。

    我们可以看到,摄像头正对的部位被成功捕获,并且反馈到我们发送邮件的邮箱中。

    通过这样的方式,我们可以在全球任意位置,向邮箱发送邮件,只要存在网络的地方,都可以实时对任意位置部署的摄像头进行监控,实时返回监控结果。

    我们打开我们的接收命令的邮箱查看一下我们接受到的邮件:

    没错,是我们刚才发送的邮件。

    我们程序文件目录下保存的截取图片:

    至此,我们的远程监控系统已经测试完毕,可见,完美达到了预期的效果!

    【系统展望】

    系统虽然功能已经实现,然还有很多不尽人意之处,未来将在第二版进行改进的有:

    1、系统每隔一定时间间隔自动进行拍照,然后图像分析是否有区别(有物体入侵),如果有立即发送邮件推送报警信息。

    2、对图片进行人脸识别,用方框圈出人连范围,以便增加提醒。

    3、系统将搭建于Raspberry Pi Linux微机系统上,并且配备摄像头全天候进行跟踪拍摄。

    4、未来可能搭建web服务,在网站或者App上进行此功能的使用

    本文为七小站主原创作品,转载请注明出处:http://www.cnblogs.com/7tiny/ 且在文章页面明显位置给出原文链接。

    作者信息(详情):

    QiXiao_柒小(東)
    Software Development
    北京市海淀区 Haidian Area Beijing 100089,P.R.China
    郵箱Email : seventiny@foxmail.com  
    網址Http: http://www.7tiny.com
    QQ:1124999434 , WeChat: wd8622088 (尽量加微信)
    (专好结交天下英雄好汉,可聊天,可谈技,可约饭,可..嗯,原则是要有的~) 更多联系方式点我哦~


    Best Regard ~
  • 相关阅读:
    《Effective C++》笔记
    《C++ Qt 编程视频教程》
    Windows下802.11抓包
    springcloud01_ribbon使用及原理
    springboot04_springboot特性之Actuator
    springboot04_手写实现starter实现
    linux操作01_redis服务器安装
    springboot03_核心特性及设计思想
    springboot重新认识
    springboot01_微服务架构的现状及未来【上】
  • 原文地址:https://www.cnblogs.com/7tiny/p/7108504.html
Copyright © 2011-2022 走看看