一、概要信息
前期准备工作我们已经做好了,下面是真正的重点,学会如何写一个 python 程序,如何将一个程序分层有序的编写好
二、程序思路
我想到了如下四个问题,如果解决了这四个问题,我们的程序基本上就大差不差了。
三、解决问题
想要解决问题最快捷的办法就是问,这也是最快速的学习方式。没有人可问的情况下,就百度
程序逻辑大致如下
1、如何获取本机外外网 IP
如何获取 IP,这即是一个问题,也提醒着我们在程序世界里面设立方法去获取 IP,这应该就是我们通常说的面向对象的基本特质之一“封装”,我们将获取 IP 这个行为封装为一个方法,如下
from json import load
from urllib.request import urlopen
def get_outer_ip():
my_ip = load(urlopen('https://ipv4.jsonip.com/'))['ip']
print(my_ip) #打印获取到的公网IP
复制代码
通过以上代码我们就可以获取一个 IP 了,然后我们通过 print 方法将 IP 输出到了控制台,这使得我联想到了作为 Java 老司机,我们不会在代码里面写 System.out.println。那么 python 又是如何同 java 一样既可以打印在控制台又能将日志输出到文件,并且还能按照一定的策略进行滚动的呢?
2、如何打印日志
通过一(bai)顿(du)操(sou)作(suo),我们知道了 python 有一个 logging 模块,那就好办了,
为了方便使用统一的日志设定,我们专门写了一个类一个方法来统一日志格式
import logging
from logging.handlers import TimedRotatingFileHandler
def set_logger():
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
# 日志打印到控制台
console_handle = logging.StreamHandler()
console_handle.setLevel(logging.DEBUG)
file_handle = logging.FileHandler('log.log', encoding='utf-8')
file_handle.setLevel(logging.NOTSET)
# 日志输出格式要求,具体可参考logging类中Formatter定义
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handle.setFormatter(formatter)
file_handle.setFormatter(formatter)
log.addHandler(file_handle)
log.addHandler(console_handle)
return log
复制代码
通过定义好了日志输出,那么我们的获取 IP 的代码就可以调整一下了
from json import load
from urllib.request import urlopen
def get_outer_ip():
my_ip = load(urlopen('https://ipv4.jsonip.com/'))['ip']
log.info("获取最新本机外网IP:%s", my_ip)
if __name__ == '__main__':
log = set_logger()
get_outer_ip()
复制代码
3、如何发现本机 IP 已变化
通过刚开始介绍的程序逻辑,我是对读取 IP 后根据上一次记录的 IP 进行比较后,判断 IP 是否已经变化的。那么我们如何读取文件记录的 IP 信息,又如何将获取到的 IP 写入文件呢。
方法一:
try:
f = open(file_name, mode='r', encoding='utf-8')
ip = f.read()
finally:
f.close()
复制代码
方法二:
with open(file_name, mode='r', encoding='utf-8') as f:
ip = f.read()
复制代码
方法二的好处在在于我们可以不用主动进行文件关闭。那么我就采用第二种方法吧,在程序逻辑上,一个是需要对文件进行读取,另外一个是要将 IP 写入到文件。对于文件的读写我也专门独立了一个类叫做 file.py,代码如下
def read(file_name):
with open(file_name, mode='r', encoding='utf-8') as f:
ip = f.read()
return ip
def write(file_name, content):
with open(file_name, mode='w', encodings='utf-8') as f:
f.write(content)
复制代码
基于以上文件读写已经 OK,那么,我们的程序可以继续完善了
import os.path
from json import load
from urllib.request import urlopen
from util.log import set_logger
from util.mail import send2self
import util.file
def get_outer_ip():
my_ip = load(urlopen('https://ipv4.jsonip.com/'))['ip']
log.info("获取最新本机外网IP:%s", my_ip)
ip_log = 'ip.txt'; # 定义一个文件名称
if os.path.exists(ip_log): # 判断文件是否存在
ip = util.file.read(ip_log) # 读取文件内容
log.info("本机上一次外网IP: %s", ip) # 打印文件内容
if not ip.__eq__(my_ip): # 判断获取的IP是否同文件中记录的一致
log.info('发送短信通知...主人')的那
send2self(my_ip, "服务器IP变化了") # 发送短信通知自己
util.file.write(ip_log, my_ip) # 将IP写入文件(覆盖)
else:
util.file.write(ip_log, my_ip) # 将IP写入文件(覆盖)
log.info("识别机器外网IP程序执行已完成,外网IP: %s", my_ip)
if __name__ == '__main__':
log = set_logger()
get_outer_ip()
复制代码
### 4、如何告诉自己
通过上面的代码完整段大家应该已经发现,除了 send2self 这个方法,其他都已经说明,下面展示一下如何发邮件通知自己吧。这里也是一样,基于单一原则,我们也独立了一个类进行邮件发送任务。下面展示的代码中,需要修改为自己的邮箱服务提供商的信息,我这里使用的是“完美邮箱”,完美邮箱可以通过与微信绑定,直接将邮件发送到自己的微信。
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
class SendEMail(object):
def __init__(self, host, port, msg_from, pwd):
self.msg_from = msg_from
self.password = pwd
# 邮箱服务器地址和端口
self.smtp_s = smtplib.SMTP_SSL(host=host, port=port)
# 发送方邮箱账号和授权码
self.smtp_s.login(user=msg_from, password=pwd)
def send_text(self, to_user, content, subject, content_type='plain'):
"""
发送文本邮件
:param to_user: 对方邮箱
:param content: 邮件正文
:param subject: 邮件主题
:param content_type: 内容格式:'plain' or 'html'
:return:
"""
msg = MIMEText(content, _subtype=content_type, _charset="utf-8")
msg["From"] = self.msg_from
msg["To"] = to_user
msg["subject"] = subject
self.smtp_s.send_message(msg, from_addr=self.msg_from, to_addrs=to_user)
def send2self(content, subject):
host = 'smtp.88.com' # 这里是邮箱服务器
port = '465' # 这里是邮箱服务器端口
msg_from = 'xxxx@88.com' # 这里调整为自己的邮箱
pwd = 'xxxxxxx' # 这里是邮箱的密码
e = SendEMail(host, port, msg_from, pwd)
e.send_text(msg_from, content, subject)
复制代码
四、问题思考
以上我们实现了如何获取 IP,并且将变化后的 IP 通过邮件的发送通知到自己,那么通过什么样的方式可以最快触达到你自己呢?通过微信公众号、服务号?企业微信?钉钉?那么这些渠道的信息通知又如何实现呢?
评论