接口应用小玩具-博客园积分排名变动监控工具

小玩具-博客园积分排名变动监控工具

一个简单的在线服务监控和提醒工具

1   概述

前段时间自己准备重新开启自己的博客园,然后还和一些圈子里面的朋友夸下海口,自己要开始像打游戏那样,进行博客园的 天梯 攀升。持续的发一些优质的文章或者随笔,然后不断地提升自己博客园的积分和排名,看自己最终将稳定在多少。

这样就造成了自己有了一个 强迫症 :

经常有事没事就去刷自己的博客,看排名变化了没(确实有点小神经质了)。然后自己也有一些关注的人,也关心着他们的排名,所以也在看自己的同时也刷着别人的页面,确实挺无聊的。

这样浪费了自己不少时间和精力,所以决定写个脚本来帮自己来做这个事情吧。

主要实现如下功能:

  • 根据指定的博客ID获取其积分和排名
  • 监测积分和排名数值的变化
  • 如果有变化会发邮件通知
  • 程序能够一直运行

2   引申场景

本文为了让文章 接地气 ,所以就使用了如上的场景。

其实本文本质上所阐述的内容本质上是一个简单的 在线服务监控和提醒工具 ,可以广泛的应用于对那些需要 7×24h 持续稳定运行的服务进行监控。只要是状态值发生了变化,就立刻进行邮件或者短信通知。在智能手机如此普遍的今天,这些消息都可以及时的推送到手机上面,能够让开发人员尽快发现服务故障并进行排查,减少IT生产损失。

3   原理分析

在博客园里面,每个用户都会有一个ID,比如我的博客的ID是 beer,然后用户的主页的格式一般www域名后面带上ID路径,比如我的主页就是:

http://www.cnblogs.com/beer/

博客园为每个用户提供了积分和排名的插件,而且一般情况下,用户都会在自己的博客主页上面加上此插件。毕竟,很多人在辛苦整理了学习笔记之后,也会关注一下自己的影响力的。如果用户在自己的博客首页加上了此插件,那么就可以在个人博客首页看到如前面所示的 积分和排名 了。

本文研究的对象就是:加入了 积分和排名 的个人博客园首页。毕竟还没有找到博客园官方提供的获取此数据的API接口。

一般查看http页面的接口,就通过web调试利器 chrome :

可以看出,在浏览器里面输入博客域名地址之后,浏览器最终呈现的内容并不是一次性的载入的。然后对主要的通讯接口进行内容查看:

发现和 积分与排名 数据相关的接口为:

http://www.cnblogs.com/beer/mvc/blog/sidecolumn.aspx?blogApp=beer

所有的侧边栏内容是通过一个独立的api来实现的。显然这个api的格式也是有一定的模板的,也是一个和博客的ID相关的URL,有两个地方是由ID动态生成的(中间一个,最后一个)。这个特性有用于我们最后将工具做成一个通用的工具,只要输入相应的博客园ID,就可以知道其api了,从而获取其积分和排名了。

4   实现方式

通过以上的分析,可以知道,要达到如上所提到的 目的 ,主要的技术手段如下:

  1. 找到用户的博客ID
  2. 通过http请求获取 积分和排名 页面的内容
  3. 解析页面获取 积分和排名 的数值
  4. 比较本次数值和上次数值的区别,如果有区别则发起通知
  5. 做一个以 博客ID 为参数的定时请求的线程
  6. 做一个无限循环的主线程,可以启用不同的 博客ID 的线程

主要功能实现如下:

主要用的标准库:

  • 解析HTML BeautifulSoup
  • 发起HTTP请求 requests
  • 运行日志记录 logging

自己写的一些包装的库:

  • MailMsg 发送邮件的对象(封装的smtplib邮件库)
  • dtlog 对logging进行的封装的指定格式的日志输出(纯粹是方便调试)

由于这两个方法具有很强的独立性,此处就不再写具体实现,用户可以自己用 print 替代 dtlog 的功能,使用 smtplib 实现MailMsg即可以运行如下程序。

# coding=utf-8
"""获取博客的排名并自动邮件通知
"""
from bs4 import BeautifulSoup
from time import sleep
import requests
import logging
import thread

from dtlib.notice import MailMsg
from dtlib.dtlog import dlog

__author__ = 'Harmo'


def get_nums(blogs_des):
    """
    get page ranks from string
    :param blogs_des:
    :return:
    """
    split_str = blogs_des.split('-')[1].strip()
    return split_str


class BlogRankMonitor(object):
    """
    博客园积分排名监控工具
    """
    def __init__(self, id):
        self.gap_seconds = 60 * 30  # 间隔时间为30min
        self.url_fmt = 'http://www.cnblogs.com/%s/mvc/blog/sidecolumn.aspx?blogApp=%s'
        self.id = id
        self.score = 0
        self.rank = 0
        self.his_score = 0
        self.his_rank = 0

    def get_blog_ranks(self):
        """
        解析页面获取博客积分和排名
        :return:
        """
        url = self.url_fmt % (self.id, self.id)
        res = requests.get(url)
        soup = BeautifulSoup(res.text)
        lis = soup.findAll('div')

        for item in lis:
            if 'sidebar_scorerank' == item.get('id'):
                li_lists = item.findAll('li')

                for li_item in li_lists:
                    if u'积分' in li_item.text:
                        self.score = get_nums(li_item.text)
                    elif u'排名' in li_item.text:
                        self.rank = get_nums(li_item.text)
                    else:
                        print 'Error'
            continue

    def monitor_score_rank(self):
        """
        监控博客积分及排名的变化
        :return:
        """
        while True:
            self.get_blog_ranks()
            if self.score != self.his_score or self.rank != self.his_rank:
                # region 发送邮件
                mail_title = '[e-notice]:blog-rank-changes'
                mail_body = "[%s]time-(score,rank):old-(%s,%s),now-(%s,%s)" \
                            % (
                                self.id,
                                self.his_score, self.his_rank,
                                self.score, self.rank
                            )
                mail_obj = MailMsg()
                mail_obj.set_title(mail_title)
                mail_obj.set_body(mail_body)
                mail_obj.send()
                dlog.debug('send mail message:%s' % self.id)
                # endregion
                self.his_score = self.score
                self.his_rank = self.rank

            sleep(self.gap_seconds)

    def start_score_rank_thread(self):
        """
        开启监控的线程
        :return:
        """
        thread.start_new_thread(self.monitor_score_rank, ())


if __name__ == '__main__':
    logging.getLogger("urllib3.connectionpool").setLevel(logging.WARNING)

    id_list = [
        'zhangfei',
        'beer'
    ]

    for id in id_list:
        blog = BlogRankMonitor(id)
        blog.start_score_rank_thread()

    #让主线程一直运行
    while 1:
        sleep(3600)

5   发布与部署

此脚本文件名称为 blogs_rank_demo.py ,在服务器上执行如下命令:

nohup python blogs_rank_demo.py &

即可在后台一直运行,如果怕机器重启后此进程结束掉,则可以在 /etc/rc.local 里面设置启动项。

当然,如果熟悉一些进程管理工具的同学,则可以使用更高级的工具,例如 supervisor 进行进程管理,这样会使得此服务的运行更稳定,更可控一些,这些都是后话了,此处略去不表了。

如下实现了周期性轮询状态变化,如果有变化则发送邮件,但是邮件不像即时消息那样立刻通知相应的人,如何能够做到发邮件后就能立刻收到提醒呢?由于目前已经是移动互联网应用如此普及的年代了,有如下两种方法可以参考:

  • 下载手机QQ邮件客户端,可以进行即时邮件提醒。
  • 使用QQ邮箱和微信绑定,关注邮件微信号,可以进行即时邮件提醒。

6   效果演示

最后让此程序运行了一段时间,对自己的博客和某个朋友的博客进行了监控。发现博客园的排名变化好久才进行更新,而且经常会是夜间或者是早上进行更新,下面是某天早上8点多的时候,收到的排名变化的提醒(由微信推送的邮件到达的提醒):

7   总结与展望

其实上面介绍的就是一个最简单的自动化监控和提醒工具的实现方式。这些思想和技术手段被广泛的应用于服务器接口监控,数据库连接监控,服务器运行状态监控等等。进行博客排名的监控只是一个好玩的小应用而已。

OK,介绍完毕,如果大家觉得有意思,或者有帮助,请点击博客下面的 推荐 ,谢谢了。

作者:

Harmo哈莫

作者介绍:

https://zhengwh.github.io

技术博客:

http://www.cnblogs.com/beer

Email:

dreamzsm@gmail.com

QQ:

1295351490

时间:

2015-10

版权声明:

欢迎以学习交流为目的读者随意转载,但是请 【注明出处】

支持本文:

如果文章对您有启发,可以点击博客右下角的按钮进行 【推荐】

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android 开发者

[译] 如何用 Android vitals 解决应用程序的质量问题

对于一个应用开发者来说,没有比开心的用户更好的衡量成功的标准,而且最好是有很多这样的用户。实现这一目标的最佳方式是拥有一个人人都想用的优秀应用,不过我们所说的“...

1391
来自专栏Aox Lei

如何搭建稳定的代理ip池, 供爬虫使用

在这篇文章之前, 应该不少人都看过很多搭建代理ip池的文章, 然后发现都是坑, 无法使用。说的比较多的 1. 推荐买xx家的代理ip, 贼稳定, 好使(广告) ...

7942
来自专栏运维小白

Linux基础(day65)

18.11 LVS DR模式搭建 LVS DR模式搭建 DR模式搭建 – 准备工作 三台机器 分发器,也叫调度器(简写为dir) 133.130 rs1 1...

2139
来自专栏WindCoder

网易MySQL微专业学习笔记(十二)-MySQL容量评估

这个系列属于个人学习网易云课堂MySQL数据库工程师微专业的相关课程过程中的笔记,本篇为其“MySQL业务优化与设计”中的MySQL数据类型相关笔记。

1371
来自专栏大数据文摘

[揭秘]基于磁盘数据的电子取证过程详解

2748
来自专栏北京马哥教育

SSH Tunnel 实践

马哥linux运维 | 最专业的linux培训机构 ---- 参考资料: http://blog.creke.net/722.html 背景介绍: 目前,线上...

2984
来自专栏即时通讯技术

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?1、引言2、系列文章3、每台电脑都必须要一个公网IP吗?4、公司的内网是如何实现内网IP地址分配和管理的?5、NAT技术:实现

搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢?另外,内行都知道,提到...

1761
来自专栏运维小白

18.11 LVS DR模式搭建

LVS DR模式搭建 DR模式搭建 – 准备工作 三台机器 分发器,也叫调度器(简写为dir) 133.130 rs1 133.132 rs2 133.133 ...

2339
来自专栏互联网技术栈

四层负载均衡转发模式

负载均衡又分为四层负载均衡和七层负载均衡。四层负载均衡工作在OSI模型的传输层,主要工作是转发,它在接收到客户端的流量以后通过修改数据包的地址信息将流量转发到应...

2033
来自专栏架构师之路

啥,又要为表增加一列属性?

需求缘起 产品第一版:用户有用户名、密码、昵称等三个属性,对应表设计: user(uid, name, passwd, nick) 第二版,产品经理增加了年龄,...

5219

扫码关注云+社区

领取腾讯云代金券