質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

pdfminerのdumppdf.pyによるPDFの目次抽出

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 162

revoiot

score 161

pdfminerというツールをインストールし使用して、pdfの中の目次(アウトライン)を抽出しようとしているのですが、下記のようなエラーが発生してしまっている状況です。
このエラーは、dumppdf.pyというファイルを書き換える必要があるというエラーでしょうか?
もしそうであれば、どのように書き換える必要があるのか、ご教授いただけると幸いです。

ShimpeinoMacBook-Pro:samples shimpei$ dumppdf.py -T JJJ.pdf
<outlines>
Traceback (most recent call last):
  File "/usr/local/bin/dumppdf.py", line 272, in <module>
    if __name__ == '__main__': sys.exit(main(sys.argv))
  File "/usr/local/bin/dumppdf.py", line 269, in main
    dumpall=dumpall, mode=mode, extractdir=extractdir)
  File "/usr/local/bin/dumppdf.py", line 151, in dumpoutline
    outfp.write('<outline level="%r" title="%s">\n' % (level, q(s)))
NameError: name 's' is not defined


画像①

画像②

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

Warning: As of 2020, PDFMiner is not actively maintained. The code still works, but this project is largely dormant. For the active project, check out its fork pdfminer.six.

メンテナンスされてないようなので、pdfminer.six で引き継がれているようです。

該当箇所の修正のみで良いなら pdfminer.six の tools/dumppdf.py#L164 より

s = e(title).encode('utf-8', 'xmlcharrefreplace')
outfp.write('<outline level="{!r}" title="{}">\n'.format(level, s))

追記: XMLのパースについて、<outline> の title 要素のリストアップは
以下のように変換できます。出力結果を sample.xml として、

import sys
import ast
import xml.etree.ElementTree as ET

# title が "b'....'" の様に多重にクォートされているのを解消する。
FIX_3K_BYTES = True

def main(filepath="sample.xml"):
    fix = ast.literal_eval if FIX_3K_BYTES else (lambda _:_)
    doc = ET.parse(filepath).getroot()
    for outline in doc.findall(r"outline"):
        title = fix(outline.attrib["title"]).decode("utf-8")
        print(title)

if __name__ == '__main__':
    main(*sys.argv[1:])

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/19 11:02

    説明不足でした。回答のコードは "b'....'" となってしまったXMLを対象にしたものなので、
    質問に貼られた画像のような出力に対応してます。<outline title="b'...'">

    他の項目でも同様の表記になるかも知れないので、根本的な解決ではありませんが。

    >"b'....'" とバイト型のリテラル表記が文字列内に入ってしまう問題が解決できるという記事

    (返信で、意図を読み違えてました)
    これは、記事というか Python 2.x -> 3.x でのよくある問題でした。
    文字列 (str) の型が 2.x では現在の bytes 相当だったのが 3.x で unicode文字となった為、
    古いライブラリ、3.x未対応なものだと同様の症状になります。


    > pdfminer.sixの中のdumppdf.pyのファイルの中身に書き換え、または追記をする必要があると思います。

    インストール済のものを書き換えるのは、極力避けたいですね。

    代わりに、問題のある関数のみ、実行時に差し替えて実行という方法もあります。

    - sys.pathでライブラリのパスを通す (site-packages ではなく別の場所にインストールされている為)
    - dumppdf.py を直接 import
    - dumppdf.e 関数の上書き

    https://github.com/pdfminer/pdfminer.six/blob/09c989f301d9cf0dca2846933113a26d07435dc8/tools/dumppdf.py#L25

    恐らく原因はここなので、ここでbytes オブジェクトを返さない等にデバッグします。

    # ---- 以下は、概要のみですが、このような感じのパッチを当てた起動スクリプトを作る
    import sys
    sys.path.append("PATH TO dumppdf.py DIRECTORY")
    import dumppdf
    dumppdf.e = FIXED_E_FUNC
    dumppdf.main()

    キャンセル

  • 2020/06/19 22:45 編集

    私自身プログラミング初心者であり、回答していただいた意図を勘違いしておりました。
    大変申し訳ございません、
    それについて、大変親切丁寧な説明をしてくださり、誠にありがとうございます。

    これから、上記のヒントを題材にして、再度チャレンジしてみようと思います。
    何度もご教授くださり誠にありがとうございます。
    よろしくお願いいたします。

    キャンセル

  • 2020/07/01 09:37

    上記を解決できるようにするために、私自身がしっかりとpythonの基礎文法を学ぶ必要があり、
    もう少し時間がかかりそうです。
    また質問が出てきた際は、大変恐れいりますが、別スレッドで投稿させていただこうと考えております。
    よろしくお願いします。

    キャンセル

+1

NameError: name 's' is not defined
とあるので、変数sを定義せずに使っていることによるエラーです。
outfp.write('<outline level="%r" title="%s">\n' % (level, q(s)))←ここの最後でしょうかね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/16 10:05

    ご回答いただきありがとうございます。
    インストールしたdumppdf.pyの中身を書き換える必要がありそうでしょうか?

    キャンセル

  • 2020/06/16 10:17

    それはdumppdfの中身を見てみないと…と思いましたが、teamiklさんが詳しく回答されてるようですね。

    キャンセル

  • 2020/06/16 12:45 編集

    ご回答いただきありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる