在微信小程序上做一個「博客園年度總結」:使用redis存儲數據

前面寫過一篇博客:在微信小程序上做一個「博客園年度總結」:解決前端獲取接口數據太慢的一種思路

當時是由於博客園接口獲取數據比較慢,所以從博客園拿到數據後,先把數據存到一個文件中,再從文件中讀取數據,這樣就不必每次都請求接口了

 

本次用redis來實現這個功能,把數據存儲到redis中,再從redis中讀取

1、本地安裝redis

因爲是在本地進行調試,所以要先在自己的電腦中安裝redis,

mac下安裝redis可參考:https://www.jianshu.com/p/2972c8e6d2f6

2、安裝rdm

爲了方便查看redis,安裝一個rdm軟件,

下載傳送門:鏈接: https://pan.baidu.com/s/1HSydI8sthcJ1ZgbIutfiAQ  密碼: 3ehk

3、使用redis

關於如何在python中使用redis,可以參考這篇博客,寫的比較清楚,傳送門:教你用Python玩轉Redis

 

(1)定義操作redis的基本方法

先創建一個conf_redis_db.py文件

# coding: utf-8
"""
author: hmk
detail: 
create_time: 
"""

import redis

r = redis.Redis(host="127.0.0.1", port=6379, decode_responses=True, charset='UTF-8', encoding='UTF-8')

# r.set("name", "測試", ex=50)
# print(r.get("name"))

EXPIRES_TIME = 86400  # 過期時間,s


def set_redis_data(key, data):
    """redis寫入數據"""
    r.set(name=key, value=data, ex=EXPIRES_TIME)


def get_redis_data(key):
    """redis讀取數據"""
    data = r.get(key)
    return data

 

(2)把博客園接口數據存儲到redis中

修改 get_cnblogs_data.py

博客園的數據是通過get_blogs_api()方法獲取的,如下

    def get_blogs_api(self, blog_name):
        """獲取個人隨筆列表接口"""
        
        flag = True
        try:
            blogs = []
            i = 1
            while flag is True:

                url = "https://api.cnblogs.com/api/blogs/{}/posts?pageIndex={}".format(blog_name, i)
                res = requests.get(url=url, headers=self.headers)
                data = res.json()

                if data:
                    # 如果接口有返回數據,就把數據追加到blogs中,同時頁碼+1
                    blogs += data
                    i += 1
                else:
                    # 如果接口返回空,說明當前傳入的頁碼已經沒有沒有數據了,結束循環
                    # print(data)
                    flag = False

            new_blogs = list(map(self.deal_blogs, blogs))  # 調用map函數處理博客原始數據

            first_blog = new_blogs[-1]  # 發佈的第一篇博客
 
            sort_blogs = sorted(new_blogs, key=lambda item: item["ViewCount"], reverse=True)  # 按照ViewCount排序,降序

            view_max_10 = sort_blogs[0:5]  # 瀏覽量前10的文章

            """提取2022年的月度數據並處理"""
            blog_date1 = [i["PostDate"][0:7] for i in new_blogs]  # 提取每條數據的年月,組成一個列表
            temp = Counter(blog_date1)
            month_blog_date = dict(temp)

            months = ["2022-01", "2022-02", "2022-03", "2022-04", "2022-05", "2022-06",
                      "2022-07", "2022-08", "2022-09", "2022-10", "2022-11", "2022-12"]

            month_result = []  # 2022年每月博客新增數量

            for j in months:  # 遍歷日期範圍列表
                if j in month_blog_date:
                    # 如果一個日期在bug列表中,說明這個日期有值,取bug字典中該日期的值賦給bug_num,同時date取當前日期,組合爲一個字典
                    month_result.append({"date": j, "value": month_blog_date[j]})
                else:
                    # 否則這個日期對應的value=0
                    month_result.append({"date": j, "value": 0})

            now_year_blog_sum = sum([i["value"] for i in month_result])  # 2022年新增博客總數

            """提取年度數據並處理"""
            blog_date2 = [i["PostDate"][0:4] for i in new_blogs]  # 提取每條數據的年,組成一個列表
            year_blog_date = dict(Counter(blog_date2))
            begin_year = first_blog["PostDate"][0:4]  # 取發佈的第一篇博客所在的年份,因爲這就是博客起始年份
            end_year = get_now_year()  # 取當年年份爲結束年份

            date_gap = int(end_year) - int(begin_year) + 1  # 計算年份差

            years = []
            for i in range(date_gap):
                years.append(str(int(begin_year) + i))

            year_result = []  # 每年博客新增數量
            for j in years:  # 遍歷日期範圍列表
                if j in year_blog_date:
                    # 如果一個日期在bug列表中,說明這個日期有值,取bug字典中該日期的值賦給bug_num,同時date取當前日期,組合爲一個字典
                    year_result.append({"date": j, "value": year_blog_date[j]})
                else:
                    # 否則這個日期對應的value=0
                    year_result.append({"date": j, "value": 0})


            res = {
                "first_blog": first_blog,  # 發佈的第一篇博客
                "view_max_10": view_max_10,  # 瀏覽量前10的文章
                "now_year_blog_sum": now_year_blog_sum,  # 2022年新增博客總數
                "month_result": month_result,  # 2022年每月博客新增數量
                "year_result": year_result  # 每年博客新增數量
            }

            return res

        except Exception as e:
            raise e

 

再寫一個方法把上述返回的數據存到redis中

from utils.conf_redis_db import *


def save_blogs(self, name):
    data = self.get_blogs_api(name)
    # print(data)

    set_redis_data("blogs_data", json.dumps(data, ensure_ascii=False))  # 需要將data轉爲字符串,同時防止中文亂碼設置ensure_ascii

因爲get_blogs_api()返回的數據爲字典格式,不能直接放到redis中,需要轉爲字符串

這裏使用json.dumps()進行轉換,同時指定ensure_asciiFalse,以避免中文亂碼

 

執行這個方法後,redis中會存儲blogs_data鍵,效果如下,

 

(3)調用redis數據

打開cnblog.py,修改GetBlogs方法,通過讀取redis中的key獲取數據

因爲在向redis寫入數據時,設置了過期時間,每隔24h會失效,當key失效時,我們會獲取到的是null

所以需要判斷這個情況,當key失效後,重新向redis寫入數據

class GetBlogs(Resource):
    """接口:獲取個人隨筆列表"""

    """使用redis數據"""
    @staticmethod
    def get():
        blog_app = cn_blogs.conf["cn_blogs"]["blogApp"]  # request.args.get("blog_app")

        data = r.get("blogs_data")
        if data is None: # 如果從redis讀取到空,說明key失效了,此時調用save_blogs()方法,重新向redis寫入數據
            cn_blogs.save_blogs(blog_app)
            return r.get("blogs_data")
        else:
            return data

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章