RAMディスク上で同ソース別カテゴリフィードのエントリを統合する。
成果物
統合
Python | 管理内容 | 保存場所 |
---|---|---|
FeedsDb.py | フィードごとの最新公開日時 | RAMディスク or 永続ディスク |
NewsSummaryDb.py | 統合したフィードのデータ | RAMディスク |
NewsDb.py | ニュース(抽出した本文を含む) | 永続ディスク |
feeds
のデータを用いてnews_summary
の登録を公開日時で限定するnews_summary
でソースを統合する(方法は後述)news_summary
のURLから本文を抽出して、news
表へ登録する(UNIQUE(url,title)
,insert or ignore ...
)
フィードのエントリは3つのテーブルを用いて3段構えで「重複なく全ニュースを取得する」ことを実現する。
コード
前回を基礎にする。
NewsSummaryDb.py
class NewsSummaryDb: ... def __is_exists_sql(self, published, url, title, schema_name=''): return """ select exists( select * from {schema_name}news where published='{published}' and url='{url}' and title='{title}') as is_exists; """.format(schema_name=self.__schema_name(schema_name), published=published, url=url, title=title) def is_exists(self, published, url, title): result = self.conn.cursor().execute( self.__is_exists_sql(published, url, title, self.__schema_ram), ).fetchone()['is_exists'] return True if 1 == result else False ...
get_news.py
... # 概要(フィード内容)のみ取得 for feed in feeds: latest_published = feedsDb.get_latest(feed) for entry in entries: ... if latest_published is not None and published < latest_published: break if summaryDb.is_exists(published, url, title): continue ... ...
本文の前にフィードのエントリを取得する。このとき、前回フィード取得時の最終更新日時より古いなら中断される。また、同日時でありながら異なるURLとタイトルを持つエントリに関しては登録する。ただし日時、URL、タイトルが同じエントリが既存ならスキップする。
既知のバグ
- 「続きを読む」から本文を抽出できないことがある。なぜか同じサイト構成であっても。
関係あるかわからんが、BeautifulSoup4.4.0以降はtext=
でなくstring=
らしい。
before
soup.find('a', text=self.__re_more_link)
after
soup.find('a', string=self.__re_more_link)
所感
ほぼ完成。でもテストしてない。無駄に複雑なのが気がかり。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- Python 3.5.3
- SQLite 3.29.0 ※
- MeCab 0.996ユーザ辞書
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux