![]() |
ノート/PDFをテキストにする (備忘 2017-04-30)http://pepper.is.sci.toho-u.ac.jp/pepper/index.php?%A5%CE%A1%BC%A5%C8%2FPDF%A4%F2%A5%C6%A5%AD%A5%B9%A5%C8%A4%CB%A4%B9%A4%EB%20%28%C8%F7%CB%BA%202017-04-30%29 |
![]() |
ノート
訪問者数 3032 最終更新 2017-05-01 (月) 14:37:54
PDFファイル(主に論文)をGoogle 翻訳に掛けるのに、Google 翻訳の入力としてそのままPDFを使うと、なんとなく変なところが出る。具体的には、文の途中に改行があったり、逆に文の切れ目が開業されていなかったりすると、どうも調子が悪いみたいだ。
というわけで、PDFを一旦テキストファイルに落として、多少整形して、かつ、Google 翻訳で対応できる長さに切る、という作業を自動化したかった。
いろいろとツールがあるようで、たとえばAcrobatでもテキスト化できる。
使いやすさを考えると、PDFファイルを食わせて変換してくれるのがいいので、プログラムで変換することを考える。自分の環境がPythonなので、コマンドで使えるレベルのプログラムか、Pythonのライブラリか、という選択になるだろう。
Pythonのライブラリである、pdftotextとpdfminerが見つかったので、いろいろと試してみた。
pdftotextは、パッケージpopplerの中に含まれているスタンドアローンプログラムで、Centos7ではyumコマンドでインストールできた。
yum install popller popller-utils pdftotext -h pdftotext version 0.26.5 Copyright 2005-2014 The Poppler Developers - http://poppler.freedesktop.org Copyright 1996-2011 Glyph & Cog, LLC Usage: pdftotext [options] <PDF-file> [<text-file>]
というところである。
これをpythonから呼び出そうというわけで、
#!/usr/bin/env python # -*- coding: utf-8 -*- import subprocess import sys import re def split5000(str): # 5000字のバッファに収まるような単位に、文の切れ目で切る cutpoints = [-1] c = 0 while True: c = c + 1 currend = min(cutpoints[-1] + 1, len(str)) if (currend >= len(str)) or (c > 5): break newend = str.rfind('\n', currend, currend+5000) +1 if newend == -1: newend = len(str) cutpoints.append(newend) return cutpoints infname = "2017-04-29_WordNet-Similarity.pdf" textfname = infname[:-4] + ".txt" args = "pdftotext " + infname + ' ' + outfname try: res = subprocess.run(args, stdout=subprocess.PIPE, shell=True) except: print("Error") with open(textfname, 'r') as f: u = f.read() out = re.sub('([^(.|\n)])\n([^\n])', r'\1 \2', u) outlist = split5000(out) for u in range(len(outlist)-1): print(out[outlist[u]+1:outlist[u+1]]) print('-----------------------------------')
新しそうなのは、pdfminer3k (pdfminerのPython3対応版らしい)である。 このパッケージ中にスタンドアローンのプログラム pdf2txt.pyがあって、同じようなことができる。
Google翻訳ページが、(意味のない)改行があると具合が悪そうなので、
更に、PDFをテキスト化した結果は、文の終りのピリオドの次が改行の場合、すぐに改行がある。(ピリオドと改行の間に空白がない。)
というわけで、やってみたのが
re.sub('([^(.|\n)])\n([^\n])', r'\1 \2', u)
但し、ファイル読み込みの時に、readlinesとかやると余分な改行が入るので、readだけでべったりと読むことにした。