美文网首页菜鸟python爬虫
做一个小爬虫监控

做一个小爬虫监控

作者: dnaEMx | 来源:发表于2015-07-20 17:21 被阅读926次

    场景和需求是这样的:

    1.机器在线数据显示在网站网页上,每次都要访问这个访问进行查询机器是否在线
    2.由于网页上已经有现成的在线数据,所以就不打算直接查询数据库进行数据获取
    3.需要定时发送一个邮件通知运维人员在线情况。(定时任务简单点用crontab)
    4.下线机器的判定是机器信息更新时间在15分钟内算是在线,否则就是下线。
    

    给予这样的场景和需求就有了以下的内容了。

    1.首先网站的数据页面找出来,可以用各种web开发工具,我这里使用的是httpfox,

    查询到这个device.php 通过post查询机器数据然后返回机器在线数据。

    关于post和get的科普:

    GET 方法请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:
    /test/demo_form.asp?name1=value1&name2=value2
    
    有关 GET 请求的其他一些注释:
    
        * GET 请求可被缓存
        * GET 请求保留在浏览器历史记录中
        * GET 请求可被收藏为书签
        * GET 请求不应在处理敏感数据时使用
        * GET 请求有长度限制
        * GET 请求只应当用于取回数据
    
    POST 方法请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
    POST /test/demo_form.asp HTTP/1.1
    Host: w3schools.com
    name1=value1&name2=value2
    
    有关 POST 请求的其他一些注释:
    
        * POST 请求不会被缓存
        * POST 请求不会保留在浏览器历史记录中
        * POST 不能被收藏为书签
        * POST 请求对数据长度没有要求
    

    http://www.w3school.com.cn/tags/html_ref_httpmethods.asp


    2.既然找到了切入点,那么就可以开始爬了。

    #!/usr/bin/python2.6
    # -*- coding: utf-8 -*-
    
    import re
    import urllib
    import urllib2
    import json
    import time
    import datetime
    
    
    def get_data():
      params = urllib.urlencode({'type':'gettable','data':'{"cpage":1,"pagesize":50,"search":{"address":{"type":"","id":0}}}'})
    
    #用urllib.urlencode是因为这样会方便将数据转为一个key|value的字典来传输数据,可用来post。
      url = 'http://XXXX/device.php' #url信息
      req = urllib2.Request(url=url,data=params)#创建请求内容,参数是url和data
      a = urllib2.urlopen(req)#进行访问页面,带着请求信息
      b = a.read()     #这写得比较简单,将访问页面的返回信息转变为json格式,然后读取json格式的内容获取需要的字段,因为我需要的数据在data字段里面,所以直接获取data为key的value信息。
      c = json.loads(b)  
      data = c['data']
    
      downs_result = []
    
      num = 0
    
      for i in data:
        down_time_start = time.strptime(str(i['servertime']), "%Y-%m-%d %H:%M:%S")
        down_time_start = datetime.datetime(down_time_start.tm_year,down_time_start.tm_mon,down_time_start.tm_mday,down_time_start.tm_hour,down_time_start.tm_min,down_time_start.tm_sec)
    
    #关于time.strptime和datetime是一种搭配使用的转换时间格式的组合。只有将时间转为真正的时间格式才能进行运算,所以需要先将"时间"用strptime转为时间字符串,然后时间字符串用datetime转为真正的时间格式
        if down_time_start < datetime.datetime.now() - datetime.timedelta(minutes=15): #这里用到timedelta来计算时间差值,timedelta会将时间转为秒数。
          timediff = datetime.datetime.now() - down_time_start
          if re.search(r'days',str(timediff)):
            timediff = re.search(r'-?(\d+)\sdays,\s(\d+):(\d+):(\d+)',str(timediff))
            downs_fno = timediff.group(1) + "天" + timediff.group(2) + "小时" + timediff.group(3) + "分钟" + timediff.group(4) + "秒"
            downs_result.append(i['name'].encode('utf-8') + '_____' + str(down_time_start) + '_____' + "(" + "下线距离现在已经过了: " + downs_fno + ")")
       num += 1
          else:
            timediff = re.search(r'(\d+):(\d+):(\d+)',str(timediff))
            downs_fno = timediff.group(1) + "小时" + timediff.group(2) + "分钟" + timediff.group(3) + "秒"
            downs_result.append(i['name'].encode('utf-8') + '_____' + str(down_time_start) + '_____' + "(" + "下线距离现在已经过了: " + downs_fno + ")")
            num += 1
    
      return (downs_result,num,len(data))
    

    参考地址:

    https://docs.python.org/2/library/json.html

    https://docs.python.org/2/library/urllib2.html#module-urllib2

    https://docs.python.org/2/library/urllib.html#urllib.urlencode

    https://docs.python.org/2/library/time.html#time.strptime

    https://docs.python.org/2/library/datetime.html


    3.然后就是发送邮件,上网抄了一下别人的例子

    import smtplib  
    from email.mime.text import MIMEText
    
    
    mailto_list=["xxx@163.com"] 
    mail_host="smtp.163.com"  #设置服务器
    mail_user="xxx@qq.com"    #用户名
    mail_pass="12345"   #口令
    
    
    def send_mail(to_list,sub,content):  #to_list:收件人;sub:主题;content:邮件内容
        me="<"+mail_user+">"   #显示发件人
        msg = MIMEText(content,_subtype='html',_charset='utf-8')    #创建一个实例,这里设置为html格式邮件
        msg['Subject'] = sub    #设置主题
        msg['From'] = me  
        msg['To'] = ";".join(to_list)  
        try:  
            s = smtplib.SMTP()  
            s.connect(mail_host)  #连接smtp服务器
            s.login(mail_user,mail_pass)  #登陆服务器
            s.sendmail(me, to_list, msg.as_string())  #发送邮件
            s.close()  
            return True  
        except Exception, e:  
            print str(e)  
            return False  
    

    完整版是这样的:

    #!/usr/bin/python2.6
    # -*- coding: utf-8 -*-
    
    import re
    import urllib
    import urllib2
    import json
    import time
    import datetime
    import smtplib  
    from email.mime.text import MIMEText
    
     
    mailto_list=["xxx@163.com"] 
    mail_host="smtp.163.com"  #设置服务器
    mail_user="xxx@qq.com"    #用户名
    mail_pass="12345"   #口令
    
    def get_data():
      params = urllib.urlencode({'type':'gettable','data':'{"cpage":1,"pagesize":50,"search":{"address":{"type":"","id":0}}}'})
      url = 'http://XXXX/device.php'
      headers = {'Content-Type': 'application/json'}
      req = urllib2.Request(url=url,data=params)
      req.add_header = ('Content-Type','application/json')
      a = urllib2.urlopen(req)
      b = a.read()
      c = json.loads(b)  
      data = c['data']
    
      downs_result = []
    
      num = 0
    
      for i in data:
        down_time_start = time.strptime(str(i['servertime']), "%Y-%m-%d %H:%M:%S")
        down_time_start = datetime.datetime(down_time_start.tm_year,down_time_start.tm_mon,down_time_start.tm_mday,down_time_start.tm_hour,down_time_start.tm_min,down_time_start.tm_sec)
        if down_time_start < datetime.datetime.now() - datetime.timedelta(minutes=15):
          timediff = datetime.datetime.now() - down_time_start
          if re.search(r'days',str(timediff)):
            timediff = re.search(r'-?(\d+)\sdays,\s(\d+):(\d+):(\d+)',str(timediff))
            downs_fno = timediff.group(1) + "天" + timediff.group(2) + "小时" + timediff.group(3) + "分钟" + timediff.group(4) + "秒"
            downs_result.append(i['name'].encode('utf-8') + '_____' + str(down_time_start) + '_____' + "(" + "下线距离现在已经过了: " + downs_fno + ")")
       num += 1
          else:
            timediff = re.search(r'(\d+):(\d+):(\d+)',str(timediff))
            downs_fno = timediff.group(1) + "小时" + timediff.group(2) + "分钟" + timediff.group(3) + "秒"
            downs_result.append(i['name'].encode('utf-8') + '_____' + str(down_time_start) + '_____' + "(" + "下线距离现在已经过了: " + downs_fno + ")")
            num += 1
    
      return (downs_result,num,len(data))
    
    
    def send_mail(to_list,sub,content):  #to_list:收件人;sub:主题;content:邮件内容
        me="<"+mail_user+">"   #显示发件人
        msg = MIMEText(content,_subtype='html',_charset='utf-8')    #创建一个实例,这里设置为html格式邮件
        msg['Subject'] = sub    #设置主题
        msg['From'] = me  
        msg['To'] = ";".join(to_list)  
        try:  
            s = smtplib.SMTP()  
            s.connect(mail_host)  #连接smtp服务器
            s.login(mail_user,mail_pass)  #登陆服务器
            s.sendmail(me, to_list, msg.as_string())  #发送邮件
            s.close()  
            return True  
        except Exception, e:  
            print str(e)  
            return False  
    
    if __name__ == '__main__':  
        downs_result,num,all=get_data()
        all = "一共有" + str(all) + "台机器"
        num = "下线的有" +str(num) + "台机器"
        downs_result = [ str(i) for i in downs_result]
        str_downs_result = "<br>".join(downs_result)
        if send_mail(mailto_list,"hello",all + "   " + num + "<br>" + str_downs_result):   #因为是html邮件,所以换行是<br>
            print "发送成功"  
        else:  
            print "发送失败" 
    

    完整版效果图

    原文链接:http://www.godblessyuan.com/2015/06/26/webcrawler_monitor/

    相关文章

      网友评论

        本文标题:做一个小爬虫监控

        本文链接:https://www.haomeiwen.com/subject/eoupqttx.html