4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PythonAdvent Calendar 2022

Day 15

ダウンロードしてきたPDFをファイルを作成せずに文字列として扱いたい

Last updated at Posted at 2022-06-02

requestsでダウンロードしてきたPDFをファイルに保存せずにstrオブジェクトとして扱う方法です。

いつもだと、下記のようにpdfとして保存しますが、
今回のケースはファイル保存せずにpythonのstrオブジェクトとして扱いたいケースです。

# PDFファイルとして保存するとき
# 今回はこれを禁止して.pdfをドライブに残さない
with open("hoge.pdf", "wb") as f:
    f.write(resp.content)
import requests
from pdftotext import PDF
from tempfile import TemporaryFile

url = 'https://github.com/progit/progit2-ja/releases/download/2.1.7/progit.pdf'
resp = requests.get(url)  # (1)

# PDFファイルとして保存するとき
# with open("hoge.pdf", "wb") as f:
#     f.write(resp.content)

# 一時ファイルに保存しないで直接`resp.content`を
# PDFインスタンス化するとエラー
# pdf = PDF(resp.content)
# => AttributeError: 'bytes' object has no attribute 'read'

# f.seek(0) しないと
# Error: poppler error creating document
# byte列が最後まで行きっぱなしなので
# f.seek(0)で最初まで戻してやる

# strオブジェクトとして扱うとき
# 一時ファイルに保存する
with TemporaryFile() as f:
    f.write(resp.content)  # (2)
    f.seek(0)  # (3)
    pdf = PDF(f)  # (4)
text = '\n'.join(pdf)  # (5)
# 10000~30000文字まで出力
print(text[10000:30000])
  1. requestsでpdfをダウンロードしてきます。
  2. バイナリを一時ファイル TemporaryFile() へ保存します。
    一時ファイルに保存しないで4の工程を行うとAttributeErrorです。
  3. ファイルを0ポジションへ移動します。これがないと次のインスタンス化でエラーです。
  4. 一時ファイルをPDFインスタンス化します。
    TemporaryFile()はガベージコレクションによってwithを抜けると破棄されます。
    tempfile --- 一時ファイルやディレクトリの作成
  5. インスタンス化されたオブジェクトはジェネレータとして扱えるので、for文などで処理できます。ここでは改行でjoinしてtextというstrオブジェクトとして取り扱います。
pdftotext.PDF.__doc__
PDF(pdf_file, password="", raw=False, physical=False)

Args:
    pdf_file: A file opened for reading in binary mode.
    password: Unlocks the document, if required. Either the owner
        password or the user password works.
    raw: If True, page text is output in the order it appears in the
        content stream.
    physical: If True, page text is output in the order it appears on
        the page, regardless of columns or other layout features.

    Usually, the most readable output is achieved by using the default
    mode, rather than raw or physical.

Example:
    with open("doc.pdf", "rb") as f:
        pdf = PDF(f)
    for page in pdf:
        print(page)

元のPDFファイルのインデントを維持したい場合はPDFインスタンス化する際にpythisicalオプションをTrueにすると良いです。

# デフォルトはphysical=False
    (...snip)
    pdf = PDF(f)
text = '\n'.join(pdf)
print(text)

"""
=>
一切管理対象になっていません (今作った .git ディレクトリに実際のところどんなファイルが含まれている
のかについての詳細な情報は、Gitの内側を参照ください)。
空のディレクトリではなくすでに存在するファイルのバージョン管理を始めたい場合は、まずそのファイルを
監視対象に追加してから最初のコミットをすることになります。この場合は、追加したいファイルについて
git add コマンドを実行したあとで git commit コマンドを行います。

$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'
これが実際のところどういう意味なのかについては後で説明します。ひとまずこの時点で、監視対象のファイ
ルを持つ Git リポジトリができあがり最初のコミットまで済んだことになります。

既存のリポジトリのクローン
"""

# physical=Trueの場合
    (...snip)
    pdf = PDF(f, pyisycal=True)
text = '\n'.join(pdf)
print(text)

"""
=>

ヘルプを見る
もし、Gitを使っている間は助けがいつも必要なら、あらゆるGitコマンドのヘルプのマニュアル・ページ
(manpage)を参照する3種類の方法があります。


 $ git help <verb>
 $ git <verb> --help
 $ man git-<verb>


例えば、configコマンドのヘルプのmanpageを次のコマンドを走らせることで見ることができます。

"""

コマンド$の前にスペースが付与されました。元のファイルがインデントついていたためでしょう。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?