1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Python] RSSから更新記事のみを取得する

Last updated at Posted at 2024-06-02

概要

  • RSSから下記の辞書形式でブログを取得する
    {"ブログタイトル":
        {"記事URL1": "記事タイトル1"},
        {"記事URL2": "記事タイトル2"},
        ...
        {"記事URLn": "記事タイトルn"}
    }
    
  • pickle形式で辞書を保存する
  • pickle形式の辞書を読み込む
  • 前回更新時の辞書との差分から更新記事のみを取得する

コード


import argparse
import feedparser
import os
import pickle
import pprint


class MoldingRSS():
    def __init__(self):
        self.blogs = []
        self.rss_dic = {}

    def add_rss_blog(self, title: str, url: str) -> None:
        """
        ブログの追加

        Parameters
        ----------
        title : str
            ブログ名
        url : str
            RSSのURL
        """
        self.blogs.append({"title": title, "url": url})

    def load_dic_pickle(self, read_dic_path: str) -> None:
        """
        RSSの辞書を格納したpickleファイルを読み込む

        Parameters
        ----------
        read_dic_pth : str
            読み込むpickleファイルのパス
        """
        load_dic = {}
        if os.path.exists(read_dic_path):
            with open(read_dic_path, "rb") as f:
                load_dic = pickle.load(f)
        self.rss_dic = load_dic

    def get_rss_dic(self) -> None:
        """
        self.blogsに格納されているRSSからリンクとタイトルを取得
        """
        for blog in self.blogs:
            f = feedparser.parse(blog["url"])
            dic = {e["link"]: e["title"] for e in f["entries"]}
            self.rss_dic[blog["title"]] = dic

    def get_dic_diff(self, tool_dic: dict) -> dict:
        """
        現在取得している辞書と対象辞書の差分を取得

        Parameters
        ----------
        tool_dic : dict
            引く側の辞書

        Returns
        -------
        dict
            差分の辞書
        """ 
        diff_dic = {}
        for blog_title, dic in self.rss_dic.items():
            diff_dic[blog_title] = []

            if tool_dic.get(blog_title, None) is None:
                continue

            for url, title in dic.items():
                if url not in tool_dic[blog_title].keys():
                    diff_dic[blog_title].append({"title": title, "url": url})
        return diff_dic

    def save_dic_pickle(self, write_dic_path: str) -> None:
        """
        RSSの辞書を格納したpickleファイルを保存する

        Parameters
        ----------
        write_dic_path : str
            書き込むpickleファイルのパス
        """
        with open(write_dic_path, "wb") as p:
            pickle.dump(self.rss_dic, p)


def main(setting_path):
    # 最新の記事リストを保存するインスタンス
    new_rss = MoldingRSS()
    # 対象のブログを"タイトル", "RSSのURL"で追加
    new_rss.add_rss_blog("ITmedia 総合記事一覧", "https://rss.itmedia.co.jp/rss/2.0/itmedia_all.xml")
    new_rss.get_rss_dic()

    # 以前取得した記事リストを保存するインスタンス
    old_rss = MoldingRSS()
    old_rss.load_dic_pickle(setting_path)

    # 辞書の差分を取得
    diff_dic = new_rss.get_dic_diff(old_rss.rss_dic)

    # 差分を保存するインスタンス
    diff_rss = MoldingRSS()
    diff_rss.rss_dic = diff_dic

    # 次回実行時に差分を確認するため、最新の記事リストをpickle形式で保存
    new_rss.save_dic_pickle(setting_path)

    # 内容表示
    print("new_rss:")
    pprint.pprint(new_rss.rss_dic)
    print("old_rss:")
    pprint.pprint(old_rss.rss_dic)
    print("diff_rss:")
    pprint.pprint(diff_rss.rss_dic)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--setting", "-s", default="all_dict.pkl")
    args = parser.parse_args()
    main(args.setting)
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?