接口應用小玩具-博客園積分排名變更監控工具

小玩具-博客園積分排名變更監控工具

一個簡單的在線服務監控和提醒工具

1   概述

前段時間本身準備從新開啓本身的博客園,而後還和一些圈子裏面的朋友誇下海口,本身要開始像打遊戲那樣,進行博客園的 天梯 攀升。持續的發一些優質的文章或者隨筆,而後不斷地提高本身博客園的積分和排名,看本身最終將穩定在多少。html

這樣就形成了本身有了一個 強迫症 :python

常常有事沒事就去刷本身的博客,看排名變化了沒(確實有點小神經質了)。而後本身也有一些關注的人,也關心着他們的排名,因此也在看本身的同時也刷着別人的頁面,確實挺無聊的。git

這樣浪費了本身很多時間和精力,因此決定寫個腳原本幫本身來作這個事情吧。github

主要實現以下功能:web

  • 根據指定的博客ID獲取其積分和排名
  • 監測積分和排名數值的變化
  • 若是有變化會發郵件通知
  • 程序可以一直運行

2   引伸場景

本文爲了讓文章 接地氣 ,因此就使用瞭如上的場景。chrome

其實本文本質上所闡述的內容本質上是一個簡單的 在線服務監控和提醒工具 ,能夠普遍的應用於對那些須要 7×24h 持續穩定運行的服務進行監控。只要是狀態值發生了變化,就馬上進行郵件或者短信通知。在智能手機如此廣泛的今天,這些消息均可以及時的推送到手機上面,可以讓開發人員儘快發現服務故障並進行排查,減小IT生產損失。數據庫

3   原理分析

在博客園裏面,每一個用戶都會有一個ID,好比個人博客的ID是 beer,而後用戶的主頁的格式通常www域名後面帶上ID路徑,好比個人主頁就是:api

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

博客園爲每一個用戶提供了積分和排名的插件,並且通常狀況下,用戶都會在本身的博客主頁上面加上此插件。畢竟,不少人在辛苦整理了學習筆記以後,也會關注一下本身的影響力的。若是用戶在本身的博客首頁加上了此插件,那麼就能夠在我的博客首頁看到如前面所示的 積分和排名 了。瀏覽器

本文研究的對象就是:加入了 積分和排名 的我的博客園首頁。畢竟尚未找到博客園官方提供的獲取此數據的API接口。bash

通常查看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
版權聲明: 歡迎以學習交流爲目的讀者隨意轉載,可是請 【註明出處】
支持本文: 若是文章對您有啓發,能夠點擊博客右下角的按鈕進行 【推薦】
相關文章
相關標籤/搜索