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


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

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

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
版權聲明: 歡迎以學習交流為目的讀者隨意轉載,但是請 【注明出處】
支持本文: 如果文章對您有啟發,可以點擊博客右下角的按鈕進行 【推薦】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM