Featured image of post Whooshを利用したPDF全文検索システムの構築

Whooshを利用したPDF全文検索システムの構築

PythonでPDF全文検索システムを作ろう(Whoosh + Flask)

プロジェクト概要

このプロジェクトは、PDFファイルの全文検索システムをPythonで構築するものです。主な特徴は:

  • Whooshを用いた高速な全文検索
  • MeCabによる日本語形態素解析
  • Flaskを使ったWebインターフェース
  • マルチスレッド処理による効率的なインデックス作成
  • 分散処理が可能なアーキテクチャ: インデックス作成(高負荷処理)と検索処理を別マシンで実行可能

コードはこちら

システムアーキテクチャ図

  1. PDFファイル
    ↓ (PyMuPDFでテキスト抽出)
  2. テキストデータ
    ↓ (MeCabで形態素解析)
  3. トークン化されたテキスト
    ↓ (Whooshでインデックス作成)
  4. 検索インデックス
    ↓ (indexディレクトリに保存)
  5. Flaskサーバー
    ↓ (Webインターフェース)
  6. ユーザー検索

各コンポーネントの役割:

  • PyMuPDF: PDFからテキストを抽出
  • MeCab: 日本語テキストを分かち書き
  • Whoosh: 全文検索用インデックスを作成
  • Flask: 検索用Webインターフェースを提供

必要なライブラリ

1
pip install whoosh pymupdf mecab-python3 flask

主要コンポーネント解説

1. PDFIndexerクラス (index_creator.py)

PDF処理の中核を担うクラスです:

1
2
3
4
class PDFIndexer:
    def __init__(self):
        # MeCabの初期化
        self.mecab = MeCab.Tagger("-Owakati -r /etc/mecabrc")
  • extract_text(): PDFからテキストを抽出(PyMuPDF使用)
  • tokenize(): 日本語テキストの分かち書き(MeCab使用)
  • process_pdf(): 1つのPDFを処理し検索用データを生成

2. インデックス作成 (index_creator.py)

Whooshのスキーマ定義とインデックス作成:

1
2
3
4
5
6
7
schema = Schema(
    title=TEXT(stored=True),       # ドキュメントタイトル
    content=TEXT,                  # 検索用(トークン化済み)
    raw_content=TEXT(stored=True), # 表示用(生テキスト)
    path=ID(stored=True),          # PDFファイルパス
    page_num=ID(stored=True)       # ページ番号
)

3. Webインターフェース (index_gui.py)

Flaskで構築された検索画面:

1
2
3
4
@app.route('/', methods=['GET'])
def search():
    query = request.args.get('q', '').strip()
    # Whoosh検索処理

主な機能:

  • HTMLテンプレートによるレスポンシブなUI
  • 検索結果のハイライト表示
  • 元PDF表示と検索結果PDF生成機能

使い方ガイド

  1. インデックス作成:
1
python index_creator.py
  1. Webサーバー起動:
1
python index_gui.py
  1. ブラウザでアクセス:
1
http://localhost:5001

学習ポイント

  1. 分散処理の利点:

    • インデックス作成(CPU/メモリ負荷が高い)は高性能マシンで実行
    • 作成済みインデックスは低性能マシンでも検索可能
    • インデックスディレクトリを共有/コピーするだけで環境構築可能
  2. Whooshの基本概念:

    • Schema: インデックスの構造定義
    • IndexWriter: ドキュメント追加用インターフェース
    • Searcher: 検索実行用インターフェース
  3. 日本語処理の工夫:

1
2
3
# MeCabで分かち書き
tokens = mecab.parse("こんにちは世界").strip()
# → "こんにちは 世界"
  1. パフォーマンス最適化:
1
2
3
# マルチスレッド処理
with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = {executor.submit(process_pdf, pdf): pdf for pdf in pdf_files}

応用例

  • 社内文書管理システム
  • 研究論文検索ツール
  • 電子書籍ライブラリ
  • マニュアル検索システム

まとめ

このプロジェクトでは、以下のPython技術を活用しています:

  1. Whoosh: 軽量な全文検索エンジン
  2. MeCab: 日本語形態素解析
  3. PyMuPDF: PDFテキスト抽出
  4. Flask: Webインターフェース構築

初心者の方は、各コンポーネントを小さく分割して理解すると良いでしょう。また、全文検索システムを探している方には、Whooshの軽量さとPythonとの親和性の高さが大きなメリットです。

Licensed under CC BY-NC-SA 4.0