Python(Flask)でRSS収集・検索サイトを構築
— AIアシスタントとのやり取りで作った記録
「立ち上げストーリー」ではサーバーやドメインの話を中心に書きました。ここでは、Python(プログラム言語)と Flask(Webサイトを作るための土台)で、RSS収集・検索サイトをどのように作っていったかを詳しく書きます。私がAIアシスタントに「こうしたい」と伝え、返ってきたコードや提案を試す。そのやり取りを具体的に交えながら、同じように挑戦したい人の参考になればと思います。
1. 最初の一言:「RSSをまとめて取得したい」
Cursor を開き、プロジェクトフォルダを作ったところから始めました。最初に打ち込んだのはこんな内容です。
AI が「feedparser(RSSを読み込むためのライブラリ=既存の道具)と requests(Webページを取得するためのライブラリ)を使うと良い」と提案してくれました。ライブラリは、自分で一から書かずに使える部品のようなものです。pip install feedparser requests で入れ、最初の rss_fetcher.py(RSS取得用のファイル)ができました。1つのURLから記事を取ってくるだけの小さなプログラムです。
2. 「複数サイト」「同じ形式で揃える」
次に、「OpenAI や Google AI など、複数のRSSをまとめて取得したい」と伝えました。
AI が config.py(設定をまとめたファイル)を作成。ここに「サイト名」と「RSSのURL」のペアを並べていきます。今では50件以上のRSSを登録しています。さらに「各サイトでフォーマットが違うので、正規化(タイトル・本文・日付・リンクを同じ形に揃えること)したい」と頼むと、HTMLタグの除去(<p> などの装飾記号を取り除くこと)や日付のフォーマット統一を行う処理が追加されました。
3. データの保存:「1行1件のJSON」
取得した記事をファイルに保存する方法を相談しました。
AI が「JSONL(1行に1件のJSON=データを文字で表す形式)が扱いやすい」と提案。1行ずつ追加・読み込みできるので、大量データになっても効率的です。storage.py で、load_items(読み込み)と save_items(保存)の関数を作りました。同じ記事(同じリンク)は重複しないように、新規のみ追加する merge_new_items_and_save も追加。「90日以上前のデータは削除したい」と伝えると、保持期間(データを残しておく日数)を設定する処理が入りました。
4. Web画面:「Flask で表示する」
データは取れるようになったので、ブラウザで見られるようにします。
Flask(Webサイトを Python で作るための土台)を導入。app.py に @app.route("/")(トップページのURLに対応する処理)を書き、render_template(HTMLテンプレートを表示する関数)で画面を表示します。templates/index.html に検索フォームと結果一覧のHTMLを用意。キーワードを GETパラメータ(URLの ?q=検索語 のように渡す値)で受け取り、検索結果を表示する流れになりました。
5. 検索ロジック:「と」で複数キーワード
検索は最初は単一キーワードだけ。「ChatGPT と Cursor について」のように、複数の語で探したいという要望を伝えました。
search.py に search_by_keywords(複数キーワードでOR検索する関数)を追加。入力欄の「と」で区切ってキーワードを分け、それぞれで検索した結果を重複なしでまとめます。また「奨学金について教えて」と入力したとき、「について教えて」を除いて「奨学金」だけを検索できるよう、query_parser.py(質問文から検索用の語を取り出すモジュール)も作りました。キーワード抽出(質問から検索に使う語を抜き出すこと)は、後でAI回答機能でも使う前提です。
6. RSS更新ボタン:「押したら取得・保存」
「RSSを更新」ボタンを押すと、最新の記事を取得して保存する機能を頼みました。
/update というURLに POST(フォーム送信でデータを送る方式)でアクセスする処理を追加。こちらから「更新して」と指示を送る形です。fetch_all で全RSSを取得し、merge_new_items_and_save で既存データに新規のみ追加。完了したら flash(画面上に「更新しました」のような一時的なメッセージを表示する機能)で結果を出します。取得に時間がかかるサイトがあっても、他のサイトの取得は続行するよう、1つ失敗しても全体が止まらない設計にしました。
7. フォルダ構成と依存関係
ファイルが増えてきたので、「どのファイルが何をしているか」を整理しました。
- app.py — 画面の表示やボタン操作の受け付け(ルーティング=URLと処理の対応づけ)
- config.py — RSSのURL一覧や設定値
- rss_fetcher.py — RSS取得・正規化
- storage.py — データの読み書き・90日保持
- search.py — キーワード検索
- query_parser.py — 質問からキーワード抽出
requirements.txt(必要なライブラリ一覧)に feedparser、flask、requests などを書き、pip install -r requirements.txt で一括インストールできるようにしました。仮想環境(venv=プロジェクトごとにライブラリを分ける仕組み)を作ってから入れると、他のプロジェクトと干渉しません。
8. 壁にぶつかったときの聞き方
うまく動かないときは、エラーメッセージをそのまま貼って「これが出た。どう直す?」と聞くことが多かったです。例えば「ModuleNotFoundError(指定したモジュールが見つからないエラー)」が出たときは、「このファイルの先頭に from config import RSS_SOURCES を追加する」といった具体的な修正案が返ってきました。「日本語が文字化けする」と伝えると、ファイル保存時の UTF-8(日本語など多言語の文字コード)指定や、ensure_ascii=False(日本語をそのまま出力するための指定)を教えてもらいました。聞くときは、「何をしたいか」と「今何が起きているか」の両方を書くと、的確な回答が返りやすいです。
9. 振り返り:段階的に積み上げる
いきなり全部作ろうとせず、「RSSを1件取る」→「複数取る」→「保存する」→「検索する」→「画面に出す」というように、小さく動くものから順に広げていきました。毎回「こうしたい」と具体的に伝え、AIが書いたコードをそのまま動かして確かめる。動いたら次の要望、動かなかったらエラー内容を共有する。その繰り返しで、気づけば一つのサイトとして形になっていました。
「立ち上げストーリー」とあわせて読むと、プログラム作成からサーバー公開までの流れがつかめると思います。同じように挑戦してみたい方は、まずは「RSSを1件取得する」ところから始めてみるのがおすすめです。
← 立ち上げストーリー
← デプロイの記録
← ボタン1つデプロイの記録
← デプロイでまたハマった話
← ログイン設定の記録
← 改善記録
← ファイル紹介の使い方
← OGP・SEOの記録
← 統合ログインの設計・経緯
← Search Console・サイトマップ
← 環境変数・.env の管理
← Git 入門・インストール
← インストール後に Git で行う設定
← カード神経衰弱の記録
← 異世界シューティングの記録
← 異世界シューティングの難易度
← 異世界戦記(全画面・迷路レイアウト)の記録
← 複数人でのゲーム進行
← 異世界衰弱(不具合の修正)
← 異世界衰弱(機能別フローチャート)
← 異世界ポイントの活用について
← 異世界ポイント市場の実装記録