2014年04月24日

PDFからテキストを抽出する

PDFの情報をテキストファイルで落としたかったので、URLを指定してテキストに変換するような簡単なスクリプトを書く。

すっかりご無沙汰でどうやって書くか忘れてしまったPythonさんを利用。そうか、xrangeはもうなかったか。

テキストの抽出にはxpdfを利用。以下、Ubuntuの場合。

# インストール
$ sudo apt-get install xpdf

# 文字コードを編集
$ sudo vi /etc/xpdf/xpdfrc

# textEncoding        UTF-8という行があるので、コメントアウトを外す

導入完了。pdftotextコマンドでPDFをテキストファイルに変換できる。1つ目の引数が対象のPDFファイル名、2つ目の引数が出力ファイル名。

$ pdftotext foo.pdf bar.txt

変換しただけだとPDF内で行替えをしているタイミングで改行コードが入ってしまう。

国勢調査の概要

◆国勢調査は、我が国の人口や世帯の実態を明らかにする国の最も基本的な統計調
査として、大正9年(1920年)以来5年ごとに実施しています。
◆国勢調査の結果は、選挙区の画定、議員定数の基準、地方交付税交付金の算定の
根拠となるなど、民主主義の基盤を成す統計を提供しています。
国勢調査の概要(http://www.stat.go.jp/data/kokusei/2010/pdf/sy02.pdf)より引用

また改ページなどで制御文字が混ざることもある。

これらをいい感じにしたかったので、Pythonで簡単なコードを書く。3.4で動作確認。下記コードをhoge.pyとか適当な名前で保存して、引数にURLと出力ファイル名を書くと動くはず。

$ python3 hoge.py http://www.stat.go.jp/info/ronbun/pdf/koku0611.pdf hoge.txt
import urllib.request
import sys
import os
import re

if len(sys.argv) < 3:
  print('Usage: ./pdf2text pdf_path outfile_path')
  sys.exit()

inputpath = sys.argv[1]
outputpath = sys.argv[2]
tmp_pdfpath = 'tmppdf.pdf'

# download pdf file if path is url
if re.match('^https?\:\/\/', inputpath):
  with urllib.request.urlopen(inputpath) as response, open(tmp_pdfpath,'wb') as output:
    output.write(response.read())
  inputpath = tmp_pdfpath

# convert pdf to text
status = os.system('pdftotext {0} {1}'.format(inputpath, inputpath + '.txt'))
if status != 0:
  print('Error: pdftotext return illegal status code ${0}'.format())
  sys.exit()

# remove pdf if download file
if os.path.exists(tmp_pdfpath):
  os.remove(tmp_pdfpath)

# remove ctrl char settings
# see http://stackoverflow.com/questions/4324790/removing-control-characters-from-a-string-in-python
mpa = dict.fromkeys(range(32))

# fix line break, remove ctrl char
with open(inputpath + '.txt') as input, open(outputpath, 'wt') as output:
  for line in input:
    if line.strip() == '':
      output.write('\n')
    else:
      output.write(line.rstrip().translate(mpa))

PDFの文書は一般的なWebの文書よりもしっかりしていることが多いので、テキストとして持っていると何かと使えるのではないだろうかと思って、ちまちま集めている。

OCRじゃないので画像で貼ってるテキストは取れない。段組が複雑なPDFとかは、文字の順序が表示と違ったりすることもある。