キャッシュレス消費者還元事業登録リストのCSV化

[2019-09-21追記] 当該サイトは,6300ページ超のPDFの公開をやめ,検索できる地図とアプリを公開しました。以下はすべて昔話になりました。

[追記] KamimuraさんがPythonコードをデバッグ・改良してくださいました(未マージ)。

[追記] uriboさんがRで実装してくださいました(「ただしJavaのメモリ不足になるため固定店舗の5533ページ分を読み込むには分割して実行する必要が ...😂」とのこと)。

[追記] PDF 571ページの 23,872 の最後の 5% が pdftotext -raw ではページ下に飛んでしまいます。バグのようです。

キャッシュレス消費者還元事業の「消費者のみなさま」のページ,ちゃんと go.jp を使っているところは偉いが,「使えるお店を探す 登録加盟店一覧はこちら」をクリックすると,なんと3600ページ6300ページ以上のPDFファイルが落ちてくる。これをCSVにしてみよう。

PDFをテキスト化するツールはいろいろあるが,ここではXpdfの一部として配布されているpdftotextコマンドを使う。ターミナルに

pdftotext -raw kameiten_touroku_list.pdf

と打ち込めば kameiten_touroku_list.txt ができる。これを次のPythonスクリプトでCSV化する:

#! /usr/bin/env python3

import sys
import re

category = 0
regexp = r"([\d,]+) ([^ ]+) ([^ ]+) (.+) ([^ ]+) ([^ ]+) (\d+%)$"
rangelim = 8
for line in sys.stdin:
    line = line.rstrip()
    m = re.search(r"([\d,]+) ", line)
    if not m:
        continue
    n = int(re.sub(",", "", m.group(1)))
    if n == 1:
        category += 1
        if category == 2:
            regexp = r"([\d,]+) (.+) (\d+%)$"
            rangelim = 4
    elif n != nprev + 1:
        continue
    nprev = n
    while not re.search(r"%$", line):
        line = line + " " + sys.stdin.readline().strip()
    m = re.search(regexp, line)
    if m:
        print(n, end="")
        for i in range(2,rangelim):
            print("," + m.group(i).strip(), end="")
        print()
    else:
        print("###", line)  # error

上記スクリプトが test.py ならば

./test.py < kameiten_touroku_list.txt > kameiten_touroku_list.csv

でCSVになる。念のため kameiten_touroku_list.csv として置いておく(文字コードはUTF-8BOM付きUTF-8)。

なお,while ... の部分は,pdftotext -raw による変換で長い行が複数行に分割されてしまうことへの対処である。pdftotext -table とすると今度は列間のスペースがなくなる行が出てくる。なかなか難しい。良いツール(あるいはpdftotextの改造法)があったら教えてください。


Last modified: