python数据变更邮件提醒_Python 路由器IP变更邮件通知

最近遇到一个问题:实验室内部的网络是通过路由器分配IP的,但是经常又需要通过校园网远程实验室内部的电脑,而路由器的外网IP是由DHCP服务器动态分配的,IP地址无法绑定成静态的。RadminViewer远程的速度比较快,但是没办法穿墙,必须知道直连的IP地址,通过在实验室的路由器上设置转发端口,就可以实现实验室内部多台电脑同时远程。但是由于路由器上IP会变,自然想到在服务器上运行一个程序,每隔一段时间监测下路由器的IP,如果变化,就发送邮件通知。

使用Python编写,由于是一个后台的程序,自然想到要做出服务,就不会有窗口一直显示。将Python程序以Windows 服务方式启动,需要用到pywin32。

本来想实现可以获取每一层的IP,因为网络可能经过了多层的IP地址转换。但还不知道怎么做,最后参考了这里的方法后,目前是只能针对TP-Link的路由器获取外网IP,其他路由器没测试过。

后面还可以进一步扩展,实现很多功能,然后可以发邮件通知。使用的时候,需要先安装服务,然后再启动。服务安装后,默认是手动启动,如果需要设置为自动启动,还需要到Windows管理工具,服务设置中,将该服务设置为自动启动。

在开发过程中,可能需要不断调试以检测是否有bug,因此可以使用调试模式,Service debug,这样可以看到print输出的内容,用于测试服务是否能正常运行。

以下是代码

1 #-*- encoding: utf-8 -*-

2

3 #Service install 安装

4 #Service start 启动

5 #Service stop 停止

6 #Service debug 调试

7 #Service remove 删除

8

9 importwin32serviceutil10 importwin32service11 importwin32event12 importsmtplib13 importtime, traceback14 importthreading15 importlogging16 importwin32evtlogutil17

18 classService(win32serviceutil.ServiceFramework):19 _svc_name_ = "IPDetector"

20 _svc_display_name_ = "IPDetector"

21 _svc_description_ = "Detect the change status of router IP, and send mail to notify user."

22 _svc_deps_ = ["EventLog"]23 _sleep_time_ = 20 * 60 #时间以秒为单位

24 _username_ = 'admin'#路由器用户名

25 _password_ = 'admin'#路由器密码

26 _routerIP_ = '192.168.1.1'#路由器内部IP

27 _mail_list_ =[28 "mail1@qq.com",29 "mail2@qq.com"

30 ]31 _currentIP_ = ''

32

33 def __init__(self, args):34 win32serviceutil.ServiceFramework.__init__(self, args)35 self.hWaitStop =win32event.CreateEvent(None, 0, 0, None)36 print u'Service is running...'

37

38 defSvcDoRun(self):39 importservicemanager40 timer =threading.Timer(self._sleep_time_, self.process())41 timer.start()42 #Write a 'started' event to the event log...

43 win32evtlogutil.ReportEvent(self._svc_name_,44 servicemanager.PYS_SERVICE_STARTED,45 0, #category

46 servicemanager.EVENTLOG_INFORMATION_TYPE,47 (self._svc_name_, ''))48 #wait for beeing stopped...

49 win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)50

51 #and write a 'stopped' event to the event log.

52 win32evtlogutil.ReportEvent(self._svc_name_,53 servicemanager.PYS_SERVICE_STOPPED,54 0, #category

55 servicemanager.EVENTLOG_INFORMATION_TYPE,56 (self._svc_name_, ''))57 return

58

59 defSvcStop(self):60   #Before we do anything, tell SCM we are starting the stop process.

61 self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)62 #And set my event

63 win32event.SetEvent(self.hWaitStop)64 return

65

66 defsend_mail(self, mail_list, msg):67 try:68 handle = smtplib.SMTP('smtp.163.com', 25)69 handle.login('mail@163.com','password')70 for mail inmail_list:71 send_msg = "To:" + mail + "\r\nFrom:mail@163.com\r\nSubject: The latest router IP \r\n\r\n"\72 + msg +"\r\n"

73 handle.sendmail('mail@163.com', mail, send_msg)74 handle.close()75 returnTrue76 except:77 printtraceback.format_exc()78 returnFalse79

80 defgetRouterPublicIP(self, username, password, routerIP):81 #this provide a way to get public ip address from tp-link

82 importhttplib, re, base6483 showErrorMessage =084

85 #192.168.1.1

86 conn =httplib.HTTPConnection(routerIP)87 #set request headers

88 headers = {"User-Agent": "python host",89 "Content-type": "application/x-www-form-urlencoded",90 "Authorization": "Basic %s" % base64.encodestring('%s:%s' % (username, password))[:-1],91 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",92 "Accept-Language": "zh-cn,zh;q=0.5",93 "Accept-Encoding": "gzip, deflate",94 "Accept-Charset": "GB2312,utf-8;q=0.7,*;q=0.7",95 "Connection": "keep-alive"}96

97 #get status page

98 conn.request("GET", "/userRpm/StatusRpm.htm", "", headers)99 response =conn.getresponse()100 keyword = re.search('wanPara [^\)]*?\)', response.read())101 response.close()102 conn.close()103

104 #search the public ip address

105 found =0106 publicIP = ""

107 ifkeyword:108 arr = re.findall('([\d]*?,)|(\"[^\"]*?\",)', keyword.group(0))109 ifarr:110 if len(arr) > 3:111 publicIP = re.search('(?<=\")[^\"]*?(?=\")', arr[2][1])112 ifpublicIP:113 publicIP =publicIP.group(0)114 found = 1

115

116 if found == 1:117 returnpublicIP118 else:119 if showErrorMessage == 1:120 logging.info('router public ip address not found.')121 #print "router public ip address not found."

122

123 defprocess(self):124 latestIP =self.getRouterPublicIP(self._username_, self._password_, self._routerIP_)125 logging.info('the latest router ip is:' +latestIP)126 #print 'the latest router ip is: ' + latestIP

127 if self._currentIP_ !=latestIP:128 _currentIP_ =latestIP129 msg = u'The latest router IP is:' +str(_currentIP_)130 print time.strftime('%Y-%m-%d %X',time.localtime(time.time()))131 ifself.send_mail(self._mail_list_, msg):132 logging.info('send mail success')133 #print 'send mail success'

134 else:135 #print 'send mail failed'

136 logging.info('send mail failed')137

138 if __name__ == '__main__':139 win32serviceutil.HandleCommandLine(Service)

这是另外一个版本,用于检测所在机器的本地IP和外网IP。

需要发送通知的邮件地址,需要以每行一个保存到当前目录下的mail.txt中,如

mail1@.gmail.com

mai2.@gmail.com

最新的本地IP地址会保存在latestIP.txt中。

IPDetector.py

1 #-*- encoding: utf-8 -*-

2 '''

3 Created on 13-5-314 '''

5

6 importsmtplib7 importtime, traceback, sys, os8 from email.mime.text importMIMEText9

10 classIPDetector():11 def __init__(self):12 pass

13

14 defsend_mail(self, subject, content):15 try:16 handle = smtplib.SMTP('smtp.163.com', 25)17 handle.login('mail@163.com', 'password')18 mail_list =self.getMailList()19 time_str = time.strftime('%Y-%m-%d %X', time.localtime(time.time()))20 msg = '

' + content + " "\22 + time_str + "by servme"+''

23 send_msg = MIMEText(msg, 'html', 'utf-8')24 send_msg['Subject'] =subject25

26 for mail inmail_list:27 handle.sendmail('servme@163.com', mail, send_msg.as_string())28 handle.close()29 returnTrue30 except:31 printtraceback.format_exc()32 returnFalse33

34 #读写最新IP信息的文件

35 defoperIPFile(self, mode, data):36 #获取脚本路径

37 path =sys.path[0]38 #判断为脚本文件还是py2exe编译后的文件,如果是脚本文件,则返回的是脚本的目录,

39 #如果是py2exe编译后的文件,则返回的是编译后的文件路径

40 ifos.path.isfile(path):41 path =os.path.dirname(path)42

43 if mode == 'read':44 file = open(path + u'\latestIP.txt')45 line =file.readline()46 file.close()47 returnline48 else:49 file = open(path + u'\latestIP.txt', 'w')50 file.write(data)51

52 defgetMailList(self):53 mailList =[]54 #获取脚本路径

55 path =sys.path[0]56 #判断为脚本文件还是py2exe编译后的文件,如果是脚本文件,则返回的是脚本的目录,

57 #如果是py2exe编译后的文件,则返回的是编译后的文件路径

58 ifos.path.isfile(path):59 path =os.path.dirname(path)60 file = open(path + u'\mail.txt')61 while 1:62 line =file.readline()63 if notline:64 break

65 mailList.append(line)66

67 file.close()68 returnmailList69

70 defgetLocalPCIP(self):71 importsocket72 localIP = socket.gethostbyname(socket.gethostname()) #得到本地ip

73 printlocalIP74

75 importre, urllib276 #获取外网IP

77 classGetExtIP:78 defgetIP(self):79 try:80 extIP = self.visit("http://www.ip138.com/ip2city.asp")81 except:82 try:83 extIP = self.visit("http://www.bliao.com/ip.phtml")84 except:85 try:86 extIP = self.visit("http://www.whereismyip.com/")87 except:88 extIP = "So sorry!!!"

89 returnextIP90

91 defvisit(self, url):92 opener =urllib2.urlopen(url)93 if url ==opener.geturl():94 str =opener.read()95 else:96 str = ''

97 return re.search('\d+\.\d+\.\d+\.\d+', str).group(0)98

99 externalIP =GetExtIP().getIP()100 printexternalIP101 returnlocalIP, externalIP102

103 #取本地IP

104 defprocess(self):105 localIP, externalIP =self.getLocalPCIP()106 currentIP = self.operIPFile('read', None)107 if currentIP !=localIP:108 self.operIPFile('write', localIP)109 time_str = time.strftime('%Y-%m-%d %X', time.localtime(time.time()))110 importsocket111 hostname =socket.gethostname()112 printhostname113 content = 'Host Name:'+ hostname + '
'\114 + 'Local IP address:' + localIP + '
'\115 + 'External IP address:' + externalIP + '
'

116 subject = "The IP address of" + hostname + "has Changed"

117 ifself.send_mail(subject, content):118 print time_str + 'send mail success'

119 else:120 print time_str + 'send mail failed'

121 else:122 print 'The IP address is same with the last detection'

123

124 if __name__=='__main__':125 ipDetector =IPDetector()126 sleep_time = 20 * 60 #时间以秒为单位

127 whileTrue:128 ipDetector.process()129 time.sleep(sleep_time)

IPService.py

1 #-*- encoding: utf-8 -*-

2 '''

3 Created on 13-6-14 '''

5 #IPService install 安装

6 #IPService start 启动

7 #IPService stop 停止

8 #IPService debug 调试

9 #IPService remove 删除

10

11 importwin32serviceutil12 importwin32service13 importwin32event14 importthreading15 importwin32evtlogutil16 importtime17

18 classService(win32serviceutil.ServiceFramework):19 _svc_name_ = "IPDetector"

20 _svc_display_name_ = "IPDetector"

21 _svc_description_ = "Detect the change status of IP, and send mail to notify user."

22 _svc_deps_ = ["EventLog"]23 _sleep_time_ = 20 * 60 #时间以秒为单位

24

25 def __init__(self, args):26 win32serviceutil.ServiceFramework.__init__(self, args)27 self.hWaitStop =win32event.CreateEvent(None, 0, 0, None)28 print 'Service is running...'

29

30 defSvcDoRun(self):31 #import servicemanager

32 #from IPDetector import IPDetector

33 #ipDetector = IPDetector()

34 #timer = threading.Timer(self._sleep_time_, ipDetector.process())

35 #timer.start()

36 #37 ## Write a 'started' event to the event log...

38 #win32evtlogutil.ReportEvent(self._svc_name_,

39 #servicemanager.PYS_SERVICE_STARTED,

40 #0, # category

41 #servicemanager.EVENTLOG_INFORMATION_TYPE,

42 #(self._svc_name_, ''))

43 #44 ## wait for beeing stopped...

45 #win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

46 #47 ## and write a 'stopped' event to the event log.

48 #win32evtlogutil.ReportEvent(self._svc_name_,

49 #servicemanager.PYS_SERVICE_STOPPED,

50 #0, # category

51 #servicemanager.EVENTLOG_INFORMATION_TYPE,

52 #(self._svc_name_, ''))

53

54 #----------------------------------------------------------------

55 importservicemanager56 #Make entry in the event log that this service started

57 servicemanager.LogMsg(58 servicemanager.EVENTLOG_INFORMATION_TYPE,59 servicemanager.PYS_SERVICE_STARTED,60 (self._svc_name_, '')61 )62 from IPDetector importIPDetector63 ipDetector =IPDetector()64 #Set an amount of time to wait (in milliseconds) between runs

65 self.timeout = 100

66 while 1:67 #Wait for service stop signal, if I timeout, loop again

68 rc =win32event.WaitForSingleObject(self.hWaitStop, self.timeout)69 #Check to see if self.hWaitStop happened

70 if rc ==win32event.WAIT_OBJECT_0:71 #Stop signal encountered

72 break

73 else:74 #Put your code here

75 ipDetector.process()76 time.sleep(self._sleep_time_)77 #Only return from SvcDoRun when you wish to stop

78 return

79 #-----------------------------------------------------------------

80

81 defSvcStop(self):82 #Before we do anything, tell SCM we are starting the stop process.

83 self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)84 #And set my event

85 win32event.SetEvent(self.hWaitStop)86

87 if __name__ == '__main__':88 win32serviceutil.HandleCommandLine(Service)

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值