説明書や仕様書などページ数が多いPDFファイルは、よく参照する章だけを別ファイルとして抽出しておくと、ページ移動の手間が減って便利です。有料のAdobe Acrobatを使えばPDFファイルから特定のページを抽出することは簡単にできますが、無料のAcrobat Readerを使っている人も多いと思います。今回は勉強も兼ねて、PythonでPDFから特定のページを抽出するプログラムを作ってみたので紹介します。

動作

下記に示したプログラムを起動すると、以下のようなGUI画面が立ち上がります。

まず「PDFファイルを開く(Open)…」ボタンを押します。ファイルを選択するダイアログが表示されるので、PDFファイルを選択して読み込みます。

するとボタン下のテキストエリアに選択したファイルのパスとページ数が表示されます。

PDFファイルが開いたら任意のページを抽出することができます。たとえば10ページ目と13~18ページ目を抽出する場合は、下のほうにあるテキストボックスに半角で「10, 13-18」と入力して、「指定したページを切り出す」ボタンを押します。

するとファイル保存ダイアログが開くので場所を指定して保存してみてください。少し処理に時間がかかりますが、処理が終わるとそれを知らせるダイアログが出ます。出力されたファイルを確認して、指定したページが抽出されていることを確認してください。

また「1ページずつ切り出す」ボタンを押すと、元のファイルと同じディレクトリに「元のファイル名_ページ数.pdf」という名前で全てのページを1枚ごとに個別のPDFファイルとして出力します。

なおページの指定を「15-1」のようにすれば15ページ目から1ページ目までページを逆順に入れ替えることもできます。こういったことは有料のAdobe Acrobatでもできないのではないでしょうか?

それでは以下にプログラムの内容を簡単に紹介しておきます。

準備

PyPDF2というモジュールを使用するので、以下のコマンドでインストールしてください。

プログラムのソースコード

プログラムの解説

PDFファイルの読み込み

103行目でPdfReaderによってPDFファイルを読み込んでいます。
104行目でPDFのページ数を調べています。
105~106行目でファイル名とページ数をテキストエリアに表示しています。

個別ページの抽出処理

116~129行目:「1ページずつ切り出す」ボタンを押したときに呼び出されるのがsplit_each_pageというメソッドです。pdf_file_reader.pages[num]で特定のページ情報を取り出せます。取り出した情報をPdfWriterオブジェクトにadd_pageメソッドで追加し、writeメソッドで書き出しています。

指定したページの抽出処理

「指定したページを切り出す」ボタンを押したときに呼び出されるのがsplit_specific_pagesというメソッドです。
139~146行目で元のファイル名の末尾に「-extracted」と付けたファイル名を作成し、保存ダイアログを表示します。

その後、テキストエリアに入力されたページ数を取り出すための処理が149~169行目です。正規表現を使って、コンマおよびハイフンで区切られた数字を取り出しています。ハイフンで区切られた場合はその間の数字も展開してページに指定します。たとえば「10-15」とあれば、それを「10, 11, 12, 13, 14, 15」に展開して、変数spec_pagesに格納します。
コンマやハイフンで区切られた数値の文字列を取り出す正規表現は以下になります。

それぞれの意味は以下になります。

  • (?!^[^\d])  →  文字列の先頭は数字以外認めない
  • (?!.*[^\d]$)  →  文字列の末尾は数字以外認めない
  • (?!.*\,-)  →  文中で「,-」と続くのは禁止
  • (?!.*-\,)  →  文中で「-,」と続くのは禁止
  • (?!.*–)  →  文中で「–」と続くのは禁止
  • [-\,\d]*  →  以上の条件を踏まえた上で、文字列は「-」「,」「数字」だけで構成される

このあたりの処理は、以下のサイトを参考にさせていただきました。

ファイルの出力についてはsplit_each_pageメソッドの処理を少し改変して実現しています。