書籍横断検索アプリ「Book Finder」

複数の図書館・書店を一括検索できるPython製Webアプリ。実装だけでなく、対象サイトのrobots.txt・利用規約の調査と判例調査まで行い、コンプライアンスを踏まえて公開範囲を判断した個人開発プロジェクトです。

個人開発 Python Streamlit API 法務・規約調査
Book Finder 検索中の画面
変更前:ミライブが在庫ありと自動表示されていた検索結果画面

変更前:ミライブの在庫を自動判定して表示

変更後:ミライブがリンクで確認バッジに変わった検索結果画面

変更後:ミライブは「リンクで確認」に切り替え

📚 プロジェクト概要

岐阜市立図書館・可児市立図書館(ミライブ)・岐阜駅本屋・草叢BOOKSの4つの施設を一括検索できるWebアプリケーションです。 書籍を探す際、複数の図書館や書店のサイトを個別に検索する手間をなくすため、1回の検索で4施設の在庫状況を同時に確認できるようにしました。

Amazonの検索結果ページへのリンク生成や、Google Books APIによる書籍概要の自動表示のほか、 メディコス・ミライブのマイページへの導線も画面上部に配置し、ログイン後の貸出状況確認までしやすい構成にしています。

⚖️ 「技術的に作れる」と「やってよい」は別物

このプロジェクトで最も大きかった学びです。スクレイピングはrequestsとBeautifulSoupがあれば誰でも書けますが、 それを実際に動かしてよいかどうかは別の問題として検証が必要でした。

robots.txtは法律ではありませんが、無視してよいものでもありません。法的拘束力がない一方で、 トラブルになった際に「禁止を知りながら続けた」という事実は、民事・刑事のどちらでも決定的に不利に働きます。 そこで対象4サイトすべてのrobots.txtと利用規約を実際に調査しました。

🔍 調査で分かったこと、参考にした判例

  • ミライブ(可児市立図書館): robots.txtが検索パスを明示的にDisallowしており、運営側も負荷軽減の注記を出していた
  • 他3サイト(岐阜市立図書館・岐阜駅本屋・草叢BOOKS): robots.txtでの禁止や明確な意思表示はなく、負荷も通常の閲覧と同等と判断

リスクの解像度を上げるために、岡崎市立中央図書館事件(Librahack事件、2010年)も調査しました。 利用者が新着図書ページを約1秒に1回という常識的な頻度でクロールしただけで、図書館システム側の欠陥による障害の責任を疑われ、 偽計業務妨害容疑で逮捕された事件です(20日間勾留、起訴猶予)。自分のアクセスが軽くても、相手のシステムが脆弱であれば トラブルに発展しうるという教訓を得ました。

🧾 サイトごとの適法性評価

対象サイトそれぞれについて、robots.txtの記載内容と現在の対応、評価を一覧にまとめました。

ミライブ(可児市立図書館) スクレイピングなし。検索結果ページへのリンク提示のみ
岐阜駅本屋(三省堂) スクレイピング継続中。robots.txtで許可されたページのみ使用
岐阜市立図書館・草叢BOOKS 個人利用の範囲でスクレイピング継続中。禁止の明示なし、負荷も通常閲覧と同等

🔄 調査結果を反映した設計判断

ミライブの自動チェック
撤去し、検索結果ページへのリンク提示のみに変更。リンク提示は自動リクエストを伴わないためスクレイピングに該当しない
他3サイトの在庫チェック
個人利用の範囲で継続。robots.txt準拠かつ負荷は閲覧と同等
アプリの公開デプロイ
しない。公開すると規約・負荷・責任の前提が変わるため、個人利用のみに限定
コードの公開
GitHubで公開。適法性の検証過程まで含めてポートフォリオとして提示

なお、ミライブについては将来的にカーリル図書館API(無償・商用可)へ切り替えることで、 自動判定を合法的に復活できることも確認済みです。

💰 収益化を見送った判断

Amazonアソシエイトや楽天アフィリエイトを使った収益化も検討しましたが、収益モデルを 「検索数 × クリック率 × 購入率 × 単価 × 料率2〜4%」で試算したところ、地域特化アプリのトラフィックでは 月数百円〜数千円が現実的な上限という結論になりました。

さらに全国の図書館横断検索は「カーリル」という完成度の高い先行サービスが無料で存在し、単純な蔵書検索では勝ち目がありません。 大規模な改修コスト・規約リスクと、期待できる収益が釣り合わないため、収益化はしないと判断しました。 「調査した結果、やらない」という意思決定も、調査の過程と根拠を残したこと自体がこのプロジェクトの成果だと考えています。

🛠️ 使用技術

Python 3.9+
メイン言語
Streamlit
WebアプリのUI作成
requests / BeautifulSoup4
HTTPリクエスト・HTML解析
ThreadPoolExecutor
4サイトへの並列リクエスト
Google Books API
書籍情報取得
ローカル実行
個人利用のみ、非公開運用

💡 技術面で工夫した点

  • 並列検索: ThreadPoolExecutorで4サイトへ同時リクエストし、体感速度を大幅に改善
  • 負荷への配慮: 検索結果を10分間キャッシュし、同一キーワードの再検索で相手サーバーへ再アクセスしない設計。User-Agentにアプリ識別子を明示
  • 堅牢性: 一部サイトが障害・エラーになっても、他サイトの結果は表示を継続するエラーハンドリング
  • 検索履歴の永続化: 直近5件の検索キーワードをローカルJSONファイルに保存し、再起動後も復元。SQLiteも検討したが単純なリスト保存にはオーバースペックと判断しあえてシンプルな構成に。検索キーワードは個人の興味関心を含むデータのため.gitignoreでリポジトリから除外
  • マイページ導線: メディコス・ミライブのマイページボタンを画面上部に配置し、ログイン後の確認動線を改善

📈 開発で学んだこと

  • 「技術的に可能」と「やってよい」は別軸で判断する必要がある
  • robots.txtの重み: 法的拘束力はなくても、明示された意思表示を無視しない
  • 判例調査の重要性: Librahack事件から、軽いアクセスでも相手システム次第でリスクになると学んだ
  • 「規制の対象外に変える」設計: 機能を削って安全側に倒す以外に、リンク提示のように規制の枠組みそのものから外れる選択肢がある
  • 収益性の見極め: 「調査した結果やらない」という意思決定も、根拠を残せば成果になる
  • Streamlitの実装知見: session_stateの扱いなど、実運用で気づいた制約への対処

🔒 公開方針

本アプリは個人利用目的で開発しており、Webアプリとしての公開デプロイは行っていません。 公開すると各サイトの利用規約・負荷・責任の前提が変わるためです。一方で、実装コードと、 今回行った適法性の調査・判断過程そのものに価値があると考え、ソースコードはGitHubで公開しています。