监控脚本

我平时比较常用的监控,有两种情况:

  • 监控某个服务器上的页面能否正常访问;
  • 监控某个 Web 页面内容的变动;

脚本是用 Python 写的,主要讨论逻辑,具体细节就不深究了,比如发 http 请求,有 N 种方案可用,没必要纠结实现方式;

监控服务器的运行状态

场景:做了个平台,用的是Windows服务器,偶尔会自动关机,需要监控服务器是否正常;

方案:python 定时发起 http HEAD 请求到服务器,看是否正确返回,如果返回错误,发送邮件通知;

while True:
    main()
    time.sleep(100)

python 版本是 2.x,每隔 100s 向服务器请求一个 js 资源,因为是 HEAD 方式,只返回响应头,不会返回实际内容,对服务器和带宽的压力比较小;

python 中设置间隔直接用 time.sleep 就可以了,参数的单位是秒。

conn = httplib.HTTPConnection("xx.ashita.top", 80, True, 2.0)
conn.request("HEAD", "/js/lib/jquery.min.js")
# conn.sock.settimeout(2.0)
res = conn.getresponse()

status = res.status
conn.close()
if status == 200:
    print get_nowtime(), 200, res.reason
else:
    print get_nowtime(), res.status, res.reason, res.getheaders()
    sendEmail(res.status, res.reason, res.getheaders())
    quit()

这块儿代码是发请求、响应,如果响应的状态码不是200,就发邮件;

httplib 是一个 python 自带的相对底层的模块,封装了 HTTP 和 HTTPS;

监控某个页面内容的变动

场景:上次的软考报名错过了,一年仅有两次考试机会,错过了非常可惜,每次的报名时间略微有些差别,想要第一时间得到报名的消息,不可能每天去官网看一下是否开始报名了,有个自动的程序监控是很有必要的;

方案:和 1 类似,定时获取页面信息,看是否开始报名;

软考官网报名页面是这样的,默认是最新考试的报名时间,取到这个年份,看是不是 2019,是的话,发送一个邮件通知;

这个地方取了所有的地域和时间,只要这些地域里边有开始报名的,就发送邮件通知;具体操作如下:

1. 发出GET请求,获取页面返回的HTML代码;

这次发送 HTTP 请求用的是第三方库 requests,需要单独安装,和自带的 urllib 系列相比,还是比较方便的;

url = 'http://bm.ruankao.org.cn/sign/welcome'
res = requests.get(url, {})
code = res.status_code
html = res.content

2. 从 HTML 代码中匹配到地域和开始报名时间;

def get_list(html):
    html = html.decode('utf-8')
    groups = re.findall(u'col1">([\u4E00-\u9FFF]+)</div>\s{0,}<div[\wA-Z\s\d\"=-]+>([\d\w\-\~]+)<', html)
    if len(groups) == 0:
        print '空'
        return None
    return groups

需要匹配的 HTML 结构是下面这一段:

<div class="layui-col-md5 col1">天津</div>
<div class="layui-col-md5 col2 timeW">2018-08-10~2018-09-13</div>

正则方面不太擅长,挨个标签、标识匹配肯定不会有错;

最终返回一个类似二维数组的结构(准确说是返回一个列表,列表中的每一项是元组),每一项包含 [地域,时间]

3. 判断并适时发邮件;

list = get_list(html)
# 循环查看是否有2019年的数据
is_in_2019 = False
for item in list:
    if re.match(r'2019', item[1]) is not None:
        is_in_2019 = True
        break
if is_in_2019:
    print u'开始报名'
    cont = get_mail_cont(list)
    sendEmail(cont)
    quit()
else:
    print get_nowtime(), u'未开始'

循环 2 返回的结果,看是否有报名时间到了 2019,如果有,发邮件通知;判断时,只看时间字符串是否是以 2019 开头的就好了;

源码地址

http://github.com/sun2dan/stack/tree/master/python/monitor

如果这篇文章对你有用,可以点击下面的按钮告诉我

0

发表回复