做一个小爬虫监控

场景和需求是这样的:

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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容

  • # Awesome Python [![Awesome](https://cdn.rawgit.com/sindr...
    emily_007阅读 2,206评论 0 3
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 2,972评论 1 3
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,458评论 6 428
  • 2017-08-16 桂湘行(三) ——暑期记录之“游桂湘” 火山 龙脊梯田沿着山形分布,层叠的绿油油,据说秋色之...
    朱明云阅读 277评论 0 1
  • 新时代的教师,首要工作非教知识,而是教授学生如何学习。教的最大善意是不教,是赋能,赋能孩子发现的能力,学习的能力,...
    Tyger老师阅读 335评论 1 5