見出し画像

PythonでPDF注釈を取り出す(PyMuPDF)

文書レビューをお願いするときに、元の文書をいじってもらいたくない場合があります。そんな時はPDFを回して注釈を付けてもらいます。
この注釈を取り出し、ExcelでOutputしてみます。今回はPyMuPDFを使います。

まずはPyMuPDFをインストールします。

!pip install PyMuPDF

fitzをimportし、PDFファイルを読み込みます。

import fitz  # PyMuPDFの別名

# PyMuPDFを使用してPDFを開く
pdf_file = 'sample.pdf'
pdf_document = fitz.open(pdf_file)

総ページ数を出してみます。

pdf_document.page_count

これを実行すると7ページと出ました。

ではどこのページに注釈があるのかを探ってみます。
ページごとにannots()を使って検出します。

for page_num in range(pdf_document.page_count):
    page = pdf_document[page_num]
    page_annotations = page.annots()
    for annotation in page_annotations:
        print(annotation)

すると、このようなOutputが出ます。

'Text' annotation on page 0 of sample.pdf
'Text' annotation on page 1 of sample.pdf
'Text' annotation on page 4 of sample.pdf

1,2,5ページに注釈があるようです。

では、info.getを使ってこれらの注釈の細かい情報を取っていきます。

for page_num in range(pdf_document.page_count):
    page = pdf_document[page_num]
    page_annotations = page.annots()
    for annotation in page_annotations:
        comment = annotation.info.get('content', '')  # ノート注釈のテキストを取得
        commenter = annotation.info.get('title', '')
        comment_time = annotation.info.get('modDate', '')
        print(page,comment,commenter,comment_time)

Outputはこんな感じです。必要なものは取れました。

page 0 of sample.pdf この文章再考してください XXX D:20231016055738+09'00'
page 1 of sample.pdf ここは6ではなく9です XXX D:20231016055809+09'00'
page 4 of sample.pdf この画像は削除してください XXX D:20231016055824+09'00'

ではこれらの情報を辞書型のlistに格納して出力します。

import fitz  # PyMuPDFの別名

# PDFファイルを開く
pdf_file = 'sample.pdf'

# PyMuPDFを使用してPDFを開く
pdf_document = fitz.open(pdf_file)

# 注釈を格納するリストを作成
annotations = []

# ページごとに注釈を取得
for page_num in range(pdf_document.page_count):
    page = pdf_document[page_num]
    page_annotations = page.annots()
    for annotation in page_annotations:
        # 注釈のプロパティを取得
        page_number = page_num + 1
        line_number = annotation.info.get('line', 0)  # 注釈の行数情報がない場合、0をデフォルト値として使用
        comment = annotation.info.get('content', '')  # ノート注釈のテキストを取得
        commenter = annotation.info.get('title', '')
        comment_time = annotation.info.get('modDate', '')

        # 注釈をリストに追加
        annotations.append({
            'Page Number': page_number,
            'Line Number': line_number,
            'Comment': comment,
            'Commenter': commenter,
            'Comment Time': comment_time,
        })

# 抽出した注釈を表示
for annotation in annotations:
    print("Page Number:", annotation['Page Number'])
    print("Line Number:", annotation['Line Number'])
    print("Comment:", annotation['Comment'])
    print("Commenter:", annotation['Commenter'])
    print("Comment Time:", annotation['Comment Time'])
    print()

# PDFを閉じる
pdf_document.close()

リストのOutputはこんな感じです。

Page Number: 1
Comment: この文章再考してください
Commenter: XXX
Comment Time: D:20231016055738+09'00'

Page Number: 2
Comment: ここは6ではなく9です
Commenter: XXX
Comment Time: D:20231016055809+09'00'

Page Number: 5
Comment: この画像は削除してください
Commenter: XXX
Comment Time: D:20231016055824+09'00'

最後にこのListを、Printではなくpandasを使ってExcelに出力します。
なお、コメント日時はD:20231016055824+09'00'では見にくいため、2023/10/16 5:58:24のような形に変換しています。

import fitz  # PyMuPDFの別名
import pandas as pd
from datetime import datetime

# PDFファイルを開く
pdf_file = 'sample.pdf'

# PyMuPDFを使用してPDFを開く
pdf_document = fitz.open(pdf_file)

# 注釈を格納するリストを作成
annotations = []

# ページごとに注釈を取得
for page_num in range(pdf_document.page_count):
    page = pdf_document[page_num]
    page_annotations = page.annots()
    for annotation in page_annotations:
        #コメント日時の日付変換
        Date = annotation.info.get('modDate', '')
        year = int(Date[2:6])
        month = int(Date[6:8])
        day = int(Date[8:10])
        hour = int(Date[10:12])
        minute = int(Date[12:14])
        second = int(Date[14:16])
        comment_time = datetime(year, month, day, hour, minute, second)
        
        # 注釈のプロパティを取得
        page_number = page_num + 1
        comment = annotation.info.get('content', '')  # ノート注釈のテキストを取得
        commenter = annotation.info.get('title', '')

        # 注釈をリストに追加
        annotations.append({
            'Page Number': page_number,
           'Comment': comment,
            'Commenter': commenter,
            'Comment Time': comment_time,
        })

# 辞書型のリストをデータフレームに変換
df = pd.DataFrame(annotations)

# Excelファイルに書き込む
file_path = 'PDF_annotation.xlsx'  # ファイル名とパスを指定
df.to_excel(file_path, index=False, engine='openpyxl')    
    
# PDFを閉じる
pdf_document.close()

無事にExcelに出力できました。

行数を取れないか色々と試したのですが、うまくいきませんでした。業務効率化の綿では、とりあえずどのページにあるかがわかればよいということにしておきます。


この記事が気に入ったらサポートをしてみませんか?