PyPDF2 - eiichiromomma/CVMLAB GitHub Wiki

PyPDF2

電子書籍の蔵書リストを作りたい

PDFの種類

  1. 出版社から電子書籍のPDF版で買ったもの
  2. 紙の本を買って,かっ捌いてスキャンしたもの(メタデータがない)
  3. 技術書典とかで買ったPDF同人誌(部分的にメタデータが無かったりする)

が買った日付とか,カテゴリごとにフォルダに放り込まれてDropBoxで同期されている状態。また,オライリーのようにDropBoxに直接降ってくるタイプのものもある。

TL;DR

タイトルと著者と場所のリストをcsvで出力。要PyPDF2。tlist.csvという名前で出力する。文字コードはUTF-8になってるという前提。

import glob
import PyPDF2
from os.path import basename, dirname
import csv
fl = glob.glob('/path/to/pdf/folders/**/*.[pP][dD][fF]')
fl += glob.glob('/path/to/yapdf/folders/**/*.[pP][dD][fF]') # 置き場が複数ある場合(例えばDropBoxの"アプリ")
tlist_csv  = ["title","author","folder"](/eiichiromomma/CVMLAB/wiki/"title","author","folder")
tlist = []
for f in fl:
    pdf = PyPDF2.PdfFileReader(f)
    print(f)
    if pdf.isEncrypted:
        try:
            pdf.decrypt('')
        except NotImplementedError:
            tlist.append([basename(f),'',dirname(f)])
            continue
    if '/Title' in pdf.documentInfo:
        if not pdf.documentInfo['/Title'] or pdf.documentInfo['/Title'] == 'Untitled':
            tlist.append([basename(f),'',dirname(f)])
        else:
            if not '/Author' in pdf.documentInfo or not pdf.documentInfo['/Author']:
                tlist.append([pdf.documentInfo['/Title'],'',dirname(f)])
            else:
                tlist.append([pdf.documentInfo['/Title'], pdf.documentInfo['/Author'],dirname(f)])
tlist_sorted = sorted(tlist, key=lambda x: (x[0],x[1])) # 書名でソート
tlist_csv += tlist_sorted
with open('tlist.csv', 'w', newline='') as file:
    writer = csv.writer(file, quoting=csv.QUOTE_ALL, delimiter=',')
    writer.writerows(tlist_csv)

PyPDF2での処理の流れ

  1. PdfFileReaderでファイルを読み込む
  2. isEncryptedで暗号化されているか確認(パスワードを打ち込むタイプでなくても売り物のPDFは大抵パス無しで暗号化されている)
  3. isEncryptedTrueならdecrypt('')で復号(空のパスワード)
  4. documentInfodictで,/Title, /Authorをキーとして読み取る

となるのだが,PyPDF2で対応できない形式もあるらしくdecryptでNotImplementedErrorでコケるのを拾って,そのときはファイル名を書名にしてしまう。 また,必ず/Title, /AuthordocumentInfo含まれているとも限らないので,それぞれ事前に確認を入れる。