前回の記事で紹介した「RSS Portal」を実際に運用してみたところ、いくつかの課題が見つかりました。今回は、それらの改善と GitHubでのOSS公開 についてまとめます。
RSS×AIで情報収集を自動化!採点&学習する自分好みの情報ポータルの作り方
運用して見つかった課題
実際に数日間運用してみると、以下の問題が発生しました。
| 問題 | 原因 |
|---|---|
| 2023年の古い記事が表示される | RSSフィードに残っている古い記事も取得していた |
| 「Zenn」の記事がズラッと並ぶ | フィード順に取得し、同一フィードの制限がなかった |
| 「Qiita」が表示されない | URLが http:// のままでフィードが取得できていなかった |
特に「Zennのトレンド」は記事数が多く、それだけで表示枠を埋めてしまう状態でした。
改善した内容
1. 古い記事を除外(14日制限)
rss_fetcher.py に、公開日が14日以上前の記事をスキップする処理を追加しました。
from datetime import datetime, timedelta
def is_article_too_old(published_at, days_limit=14):
"""記事が古すぎるかチェック"""
if not published_at:
return False
pub_date = datetime.fromisoformat(published_at)
cutoff_date = datetime.now() - timedelta(days=days_limit)
return pub_date < cutoff_date
# fetch_single_feed() 内で使用
for entry in feed.entries:
published_at = parse_published_date(entry)
# 14日以上前の記事はスキップ
if is_article_too_old(published_at):
continue
2. 同一フィードからの表示制限
database.py の get_scored_articles() に、同一フィードから最大10件までという制限を追加しました。
from collections import defaultdict
def get_scored_articles(min_score=1, limit=100, max_per_feed=10):
"""スコアリング済みの記事を取得(同一フィード制限付き)"""
# まず全件取得
all_articles = fetch_all_scored_articles(min_score)
# 同一フィードからの記事数を制限
feed_count = defaultdict(int)
filtered_articles = []
for article in all_articles:
feed_name = article['feed_name']
if feed_count[feed_name] < max_per_feed:
filtered_articles.append(article)
feed_count[feed_name] += 1
if len(filtered_articles) >= limit:
break
return filtered_articles
3. 表示順を「投稿日順」に変更
以前は fetched_at(取得日時)でソートしていたため、リライトされた古い記事が上位に来ることがありました。
-- 変更前
ORDER BY a.fetched_at DESC, a.ai_score DESC
-- 変更後
ORDER BY a.published_at DESC, a.ai_score DESC
これにより、投稿日が新しい順 → 同日内はスコア順 という自然な並びになりました。
4. フィードの整理と海外サイト追加
実際に参考にしているサイトに厳選しました。
整理後: 約20フィード(厳選 + 海外サイト追加)
追加した海外フィード:
| サイト | 特徴 |
|---|---|
| CSS-Tricks | フロントエンド技術の定番 |
| Codrops | インタラクティブなUI/UXの実装例 |
| Smashing Magazine | Web制作全般の深掘り記事 |
| Ahmad Shadeed | CSS実装パターンの詳細解説 |
| Josh W Comeau | CSS/Reactのインタラクティブな解説 |
海外サイトの記事も、AIが日本語で要約してくれるので問題なく読めます。
設定値のチューニング
config.py の設定を調整しました。
| 設定項目 | 変更前 | 変更後 | 理由 |
|---|---|---|---|
MAX_ARTICLES_PER_FETCH |
100 | 2000 | 全フィードから取得するため |
MAX_ITEMS_PER_FEED |
20 | 100 | フィルタリング前に十分な母数を確保 |
MAX_DISPLAY_PER_FEED |
なし | 10 | 同一フィードの偏りを防止 |
ARTICLE_RETENTION_DAYS |
14 | 14 | 維持 |
改善後の結果

- 日付順に並ぶな2026-01-31 → 01-30 → 01-29...
- フィードが分散なZenn、Qiita、コリス、npaka など様々なソースから表示
- 古い記事なしな14日以内の記事のみ
GitHubで公開しました
RSS Portal をOSSとして公開しました。
GitHub: sarap422/api-rss-portal
含まれるファイル
api-rss-portal/
├── api/rss-portal/
│ ├── main.py # FastAPI本体
│ ├── config.py # 設定(APIキー、興味分野)
│ ├── rss_fetcher.py # RSS取得
│ ├── ai_scorer.py # AIスコアリング
│ ├── database.py # SQLite操作
│ ├── json_output.py # JSON出力
│ ├── cron_job.py # 定期実行
│ └── data/feeds.opml # サンプルフィード
├── public_html/api/rss-portal/
│ └── .htaccess # プロキシ設定
├── rss-portal.php # WordPress組み込み用
└── README.md
使い方
- ファイルをサーバーに配置
config.pyでAPIキーと興味分野を設定data/feeds.opmlにRSSフィードを登録- Cronで定期実行を設定
- WordPressに
rss-portal.phpを組み込み
詳細はREADMEを参照してください。
興味のある方はGitHubからクローンして、ぜひ自分好みにカスタマイズしてみてください。
関連記事
RSS×AIで情報収集を自動化!採点&学習する自分好みの情報ポータルの作り方
関連リンク
- GitHub: sarap422/api-rss-portal
- OpenRouter: https://openrouter.ai/
