きっかけ
春の人事異動に向けてWebページの改定が必要になりました。
URLの一覧からChromeの --print-to-pdf オプションを使ってすべてのページをPDFに落として修正が必要な個所にすべて注釈を入れたけど、一覧にして管理したいからPDFから注釈を全部引っこ抜けないだろうか?
PDFMinerを使う
よく調べてみると、GitHubに4年前に書かれた extract_pdf_comments.py というphthon2系らしきソースがあるのでこれを試す
動作環境
いつものSurface3 (Win10 x64)
Phthon 3.6.4
PDFMinerの導入
ここを参考に PDFMiner.six を導入する
前提条件としてVS2015とpycryptoが必要なのでここを参考に入れる
ソースを直す
エラーメッセージと闘いながらpython3 向けの修正と日本語対応を行う。サンプルソースは以下のように変化した。
extract_pdf_comments.py
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdftypes import PDFObjectNotFound
pages = []
def extract(objid, obj):
global pages
if isinstance(obj, dict):
# 'Type' is PDFObjRef type
if 'Type' in obj and obj['Type'].name == 'Page':
pages.append(objid)
elif 'C' in obj:
pr = obj['P']
try:
pi = pages.index(pr.objid)+1
except:
pi = -1
print(objid,pi, obj['Subj'].strip(b'\xfe\xff').decode('utf-16be'),obj['T'].decode(),obj['Contents'].strip(b'\xfe\xff').decode('utf-16be')
fp = open("sample.pdf", 'rb')
parser = PDFParser(fp)
doc = PDFDocument(parser, "")
visited = set()
for xref in doc.xrefs:
for objid in xref.get_objids():
if objid in visited: continue
visited.add(objid)
try:
obj = doc.getobj(objid)
if obj is None: continue
extract(objid,obj)
except PDFObjectNotFound as e:
print >>sys.stderr, 'not found: %r' % e
これを実行するとこんな感じで出力される
51 9 ハイライト表示 user 表題:部署名の変更
55 9 ハイライト表示 user マネージメントの入れ替え
57 9 ハイライト表示 user 要検討:部署名の変更?言い回しの変更?
59 9 ハイライト表示 user 2018/4の記事を追加
実際にはこれをフォルダ指定して存在するPDFファイルをすべて処理して、ファイル名も含めてカンマ区切りで出力するように変更している。
(2018/2/22追記)
現状のソースでは、ユーザー名は英数字のみで、コメントは日本語で何かが記入されている(無記入でない)ことが前提になっています。
マーキングだけしてコメントを入力しないと、"Contents"がないとか言われてエラーになります。
おまけ
URLの一覧からWebページをPDFとして保存する
printPDF.bat
REM chrome \
REM --headless \ # Chrome をヘッドレスモードで実行する
REM --disable-gpu \ # 暫定的に必要なフラグ
REM --remote-debugging-port=9222 \
REM https://www.chromestatus.com # 開きたい URL(デフォルトは about:blank)
REM
REM CSVの書式は、 #,<url>,<filename>
REM
set curdir=C:\tmp
set csvfile=%curdir%\url.csv
set chromedir="C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
for /f "tokens=1,2,3 delims=," %%a in (%csvfile%) do (
%chromedir% --headless --disable-gpu --print-to-pdf=%curdir%\%%c.pdf %%b)