python-----监控博客园积分动态,有变化发邮件通知

闲来无事,平时喜欢时不时看看博客积分和博客排名,而这样总是很浪费时间,所以写了如下代码,实现积分有变化,就发邮件通知,代码如下:

blogs_rank.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/1/9 23:08
# @Author  : xiaodai

"""获取博客的排名并自动邮件通知
"""
from bs4 import BeautifulSoup
from time import sleep
import requests
import logging
import _thread
from send_e import send_email
import datetime

__author__ = 'xiaodai'

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, "lxml")
        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 = '[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
                            )
                send_email(mail_title,mail_body)
                print(datetime.datetime.now())
                print('send mail message:%s' % self.id)
                self.his_score = self.score
                self.his_rank = self.rank
                print(self.his_score)
                print(self.his_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 = [
        'xiaodai0'
    ]
    for id in id_list:
        blog = BlogRankMonitor(id)
        blog.start_score_rank_thread()
    # 让主线程一直运行
    while 1:
        sleep(3600)

send_e.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/1/9 23:18
# @Author  : xiaodai

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.header import Header
import datetime

def send_email(mail_title,mail_body):
    # 设置smtplib所需的参数
    # 下面的发件人,收件人是用于邮件传输的。
    smtpserver = 'smtp.163.com'
    username = 'xxx@163.com'
    password = 'xxxxxx'
    sender = 'xxx@163.com'
    # 收件人为多个收件人
    receiver = ['xxx@qq.com','xxx@126.com']

    subject = mail_title
    # 通过Header对象编码的文本,包含utf-8编码信息和Base64编码信息。以下中文名测试ok
    # subject = '中文标题'
    # subject=Header(subject, 'utf-8').encode()

    # 构造邮件对象MIMEMultipart对象
    # 下面的主题,发件人,收件人,日期是显示在邮件页面上的。
    msg = MIMEMultipart('mixed')
    msg['Subject'] = subject
    msg['From'] = 'xxx@163.com <xxx@163.com>'
    # msg['To'] = 'XXX@126.com'
    # 收件人为多个收件人,通过join将列表转换为以;为间隔的字符串
    msg['To'] = ";".join(receiver)
    # msg['Date']='2012-3-16'

    # 构造文字内容
    text = mail_body
    text_plain = MIMEText(text, 'plain', 'utf-8')
    msg.attach(text_plain)

    # # 构造图片链接
    # sendimagefile = open(r'E:\test\JPEGImages\001726.jpg', 'rb').read()
    # image = MIMEImage(sendimagefile)
    # image.add_header('Content-ID', '<image1>')
    # image["Content-Disposition"] = 'attachment; filename="testimage.png"'
    # msg.attach(image)

    # # 构造html
    # # 发送正文中的图片:由于包含未被许可的信息,网易邮箱定义为垃圾邮件,报554 DT:SPM :<p><img src="cid:image1"></p>
    # html = """
    # <html>
    #   <head></head>
    #   <body>
    #     <p>Hi!<br>
    #        How are you?<br>
    #        Here is the <a href="http://www.baidu.com">link</a> you wanted.<br>
    #     </p>
    #   </body>
    # </html>
    # """
    # text_html = MIMEText(html, 'html', 'utf-8')
    # text_html["Content-Disposition"] = 'attachment; filename="texthtml.html"'
    # msg.attach(text_html)

    # 构造附件
    # sendfile = open(r'E:\test\123.txt', 'rb').read()
    # text_att = MIMEText(sendfile, 'base64', 'utf-8')
    # text_att["Content-Type"] = 'application/octet-stream'
    # # 以下附件可以重命名成aaa.txt
    # # text_att["Content-Disposition"] = 'attachment; filename="aaa.txt"'
    # # 另一种实现方式
    # text_att.add_header('Content-Disposition', 'attachment', filename='aaa.txt')
    # # 以下中文测试不ok
    # # text_att["Content-Disposition"] = u'attachment; filename="中文附件.txt"'.decode('utf-8')
    # msg.attach(text_att)

    # 发送邮件
    smtp = smtplib.SMTP()
    smtp.connect('smtp.163.com')
    # 我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。
    # smtp.set_debuglevel(1)
    smtp.login(username, password)
    smtp.sendmail(sender, receiver, msg.as_string())
    smtp.quit()
    print('发送成功!',datetime.datetime.now())

if __name__ == '__main__':
    mail_title='[e-notice]:blog-rank-changes'
    mail_body = "[%s]time-(score,rank):old-(%s,%s),now-(%s,%s)"
    send_email(mail_title,mail_body)

 

posted @ 2019-01-15 10:26  小呆丶  阅读(283)  评论(0编辑  收藏  举报