PythonでPDFファイルの文書情報の取得と書き換え
PyPDF2モジュールを使って、PDFファイルの文書情報(メタデータ)を取得したり書き換えたりしてみました。
目次
文書情報の読み取りの手順
PDFファイルには、文書として表示される情報の他に文書の著者などの情報(メタデータ)が入っています。こういった情報をPythonのPyPDF2モジュールを使って読み取ってみます。
PDFファイルのメタデータの格納方法は私の知る限りでは3種類あります。
Document Information Dictionary
Metadata stream
Extensible Metadata Platform (XMP)
Extensible Metadata Platform は、PDF 2.0以降で採用された方法です。
ここで読み取るメタデータは、Document Information Dictionary に格納されているデータです。
おおまかな手順は下記です。
PdfFileReaderでファイルを読み取る。
getDocumentInfoメソッドでDocumentInformationクラスのオブジェクトを作る。
DocumentInformationオブジェクトのプロパティにアクセスする。
情報取得に使用するクラスとメソッド
PdfFileReaderクラス
reader = PyPDF2.PdfFileReader(stream, [strict], [warndest], [overwriteWarnings])
名前 |
型 |
内容 |
---|---|---|
stream |
PDFファイルのパスを示す文字列、またはreadとseekに対応したオブジェクト。 |
|
strict |
bool |
省略可。既定値はTrue。PDFファイルを読み取ったときの警告を表示するかどうか。 |
warndest |
省略可。既定値はsys.stderr。警告の出力先。 |
|
overwriteWarnings |
bool |
省略可。既定値はTrue。 |
reader |
PdfFileReaderオブジェクト。 |
PdfFileReaderオブジェクトを作成します。
getDocumentInfoメソッド
docinfo = reader.getDocumentInfo()
名前 |
型 |
内容 |
---|---|---|
reader |
PdfFileReaderオブジェクト。 |
|
docinfo |
PDFファイルの文書情報を格納したDocumentInformationオブジェクト。 |
DocumentInformationオブジェクトを作成するメソッドです。Document Information Dictionaryにメタデータが無い場合は、Noneが返ります。
DocumentInformationクラス
下表のプロパティがあります。
プロパティ |
内容 |
---|---|
author |
文書の著者。 |
author_raw |
|
creator |
文書の作成者。 |
creator_raw |
|
producer |
文書ファイルの生成ソフトウェア。 |
producer_raw |
|
subject |
文書の件名。 |
subject_raw |
|
title |
文書のタイトル。 |
title_raw |
戻り値の型は、TextStringObjectというUnicode文字列です。プロパティの最後がrawになっているものは、ByteStringObjectが返ってきます。値が設定されていないプロパティを参照した場合は、Noneが返ります。
これらのプロパティは読み込み専用で、プロパティに値をセットすることはできません。値を代入しようとするとエラーになります。
メタ情報の取得例
青空文庫からダウンロードした「こころ」のテキストをワードパッドに貼り付けて、PDFファイルとしてプリントしたものを作ります。このPDFファイルのメタデータを表示してみます。
ちなみに、AcrobatでこのPDFファイルのプロパティを表示させると、こんな感じになっています。
では、下記のコードでPDFファイルのプロパティを表示してみましょう。
import PyPDF2
with open('kokoro.pdf', mode='rb') as f:
reader = PyPDF2.PdfFileReader(f)
docinfo = reader.getDocumentInfo()
print(docinfo.title) # プロパティを指定する方法
for i in docinfo.keys():
print(i + '\t' + docinfo[i]) # 全てのプロパティを表示
タイトルを表示した後に、forループを使って全てのプロパティを表示させました。実行すると下記のようになります。
> python pdf_test.py
PdfReadWarning: Superfluous whitespace found in object header b'484' b'0' [pdf.py:1666]
kokoro.rtf
/Author xxxxxx
/CreationDate D:20200531094652+09'00'
/ModDate D:20200531094652+09'00'
/Producer Microsoft: Print To PDF
/Title kokoro.rtf
Authorのところは、おそらくWindowsのログイン名が入るのではないかと思います。
変換元がワードパッドなので、Titleがrtfファイルのファイル名になっています。
PDFに印刷したので、Print To PDFがProducerになってますね。
文書情報(メタデータ)の削除と書き換え
DocumentInformationオブジェクトのプロパティは読み込み専用なので、ダイレクトに書き換えはできません。しかし、新しく値をセットすることはできます。
そこで、メタデータをいったん削除してから新しく書き込むことで、書き換えを実現してみます。
DocumentInformationは辞書なので、popやdelでアイテムの削除ができます。
上でメタデータを読み取ったPDFファイルから、Producerを削除して、Authoerをfooに書き換えてみます。
書き換えに使用するクラスとメソッド
PdfFileWriterクラス
writer = PyPDF2.PdfFileWriter()
名前 |
型 |
内容 |
---|---|---|
writer |
PdfFileWriterオブジェクト。 |
PdfFileWiterクラスは、ページオブジェクトをPDFファイルに書き込むためのクラスです。
cloneReaderDocumentRootメソッド
writer.cloneReaderDocumentRoot(reader)
名前 |
型 |
内容 |
---|---|---|
writer |
PdfFileWriterオブジェクト。 |
|
reader |
コピー元となるPdfFileReaderオブジェクト。 |
PdfFileWriterオブジェクトにPdfFileReaderオブジェクトのドキュメントルートをコピーするメソッドです。
addMetadataメソッド
writer.addMetadata(infos)
名前 |
型 |
内容 |
---|---|---|
writer |
PdfFileWriterオブジェクト。 |
|
infos |
dict |
メタデータのフィールド名をキーにした辞書。 |
PdfFileWriterオブジェクトにメタデータを書き込むメソッドです。引数はメタデータの辞書です。
writeメソッド
writer.write(stream)
名前 |
型 |
内容 |
---|---|---|
writer |
PdfFileWriterオブジェクト。 |
|
stream |
ファイルオブジェクト、またはwriteとtellに対応したオブジェクト。 |
ファイルオブジェクトに書き込みをします。withおよびopenと共に使うのが良いでしょう。
メタ情報書き換えの実施例
では下記のコードで試してみます。
import PyPDF2
reader = PyPDF2.PdfFileReader('kokoro.pdf', strict=False)
docinfo = reader.getDocumentInfo()
# 元ファイルのメタデータの表示
for i in docinfo.keys():
print(i + '\t' + docinfo[i])
# メタデータを新しい辞書にコピー
modified_info = {k: docinfo[k] for k in docinfo.keys()}
# 書き出し用オブジェクトを生成して本体データをコピー
writer = PyPDF2.PdfFileWriter()
writer.cloneReaderDocumentRoot(reader)
# 辞書を加工してメタデータを書き込み
modified_info.pop('/Producer')
modified_info['/Author'] = 'foo'
writer.addMetadata(modified_info)
print('Modified meta data :')
for i in modified_info.keys():
print(i + '\t' + modified_info[i])
# PDFファイル出力
with open('out.pdf', mode='wb') as f:
writer.write(f)
出力はこうなります。
> python pdf_test.py
/Author xxxxxx
/CreationDate D:20200531094652+09'00'
/ModDate D:20200531094652+09'00'
/Producer Microsoft: Print To PDF
/Title kokoro.rtf
Modified meta data :
/Author foo
/CreationDate D:20200531094652+09'00'
/ModDate D:20200531094652+09'00'
/Title kokoro.rtf
出力されたPDFファイルのプロパティをAcrobatで表示してみるとこうなります。
Authorは書き換わりました。
Titleは最初のままですね。
Producerは削除したのですが、PyPDF2になっています。Producerの指定をしないとPyPDF2が自動的に書き込まれるようですね。Producerを書き込まないようにしたい場合は、Producerを削除するのではなく、Producerに空の文字列を指定するとPyPDF2と書き込まれなくなります。
公開日
広告