LoginSignup
0
2

More than 3 years have passed since last update.

ベルマーク教育助成財団の週別ベルマーク受付状況のPDFから都道府県別・市区町村別に集計する

Last updated at Posted at 2020-11-12

はじめに

ベルマーク教育助成財団週別ベルマーク受付状況のPDFから都道府県別・市区町村別に集計しました

現在はウェブベルマークというのも始まっていてウェブベルマークサイトからお好きなショップにアクセスお買い物に応じてベルマークポイントがたまります

利用可能ショップ

ウェブベルマーク.png

じゃらんや楽天トラベルなども利用可能なのでGo To トラベルを申し込む前にご利用するだけで、自己負担なく支援できます。

※要事前登録

説明

こちらの処理はX座標、Y座標のlimitの範囲にあるのもを多い座標の位置に集約しています
文字数が多く2段になっているものや、多少ずれているところを調整しています

def snap_adjustment(s, limit=5):

    count = s.value_counts().sort_index()

    index = 0
    value = 0

    for i, v in count.items():

        if (i - index) < limit:

            if v > value:
                s = s.replace(index, i)
                index = i
                value = v

            else:
                s = s.replace(i, index)

        else:
            index = i
            value = v

    return s

プログラム

import pathlib
import time

import pandas as pd
import pdfplumber
import requests
from bs4 import BeautifulSoup


def fetch_file(url, dir="."):

    r = requests.get(url)
    r.raise_for_status()

    p = pathlib.Path(dir, pathlib.PurePath(url).name)
    p.parent.mkdir(parents=True, exist_ok=True)

    with p.open(mode="wb") as fw:
        fw.write(r.content)
    return p


def snap_adjustment(s, limit=5):

    count = s.value_counts().sort_index()

    index = 0
    value = 0

    for i, v in count.items():

        if (i - index) < limit:

            if v > value:
                s = s.replace(index, i)
                index = i
                value = v

            else:
                s = s.replace(i, index)

        else:
            index = i
            value = v

    return s


url = "https://www.bellmark.or.jp/collect/accept.htm"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}

r = requests.get(url, headers=headers)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

links = {
    href.get("href")
    for href in soup.select("div.cal-process > div.cal-row-date > div > a")
}

dfs = []

for link in links:

    p = fetch_file(link)

    with pdfplumber.open(p) as pdf:

        for page in pdf.pages:

            crop = page.within_bbox((0, 65, page.width, page.height - 40))

            df_tmp = (
                pd.DataFrame(crop.extract_words(keep_blank_chars=True))
                .astype({"x0": float, "x1": float, "top": float, "bottom": float})
                .sort_values(["top", "x0"])
            )

            df_tmp["top"] = snap_adjustment(df_tmp["top"], 6)
            df_tmp["x0"] = snap_adjustment(df_tmp["x0"])

            table = (
                df_tmp.pivot_table(
                    index=["top"],
                    columns="x0",
                    values="text",
                    aggfunc=lambda x: "".join(str(v) for v in x),
                )
            ).values

            df = pd.DataFrame(table, columns=["都道府県", "市", "区町村", "参加団体", "受付日"])
            dfs.append(df)

            time.sleep(3)

df = pd.concat(dfs)

df

df["市区町村"] = df["市"].fillna("") + df["区町村"].fillna("")

df1 = df.reindex(columns=["都道府県", "市区町村", "参加団体", "受付日"])

df1.to_csv("data.csv")

df1

都道府県別

import japanize_matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["figure.dpi"] = 200

df1["都道府県"].value_counts(ascending=True).plot.barh(figsize=(5, 10))
# グラフを保存
plt.savefig("01.png", dpi=200, bbox_inches="tight")
plt.show()

01.png

市区町村別

s = df1.groupby(["都道府県", "市区町村"])["市区町村"].count().sort_values(ascending=True)

s.tail(50).plot.barh(figsize=(5, 10))

# グラフを保存
plt.savefig("02.png", dpi=200, bbox_inches="tight")
plt.show()

02.png

0
2
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
0
2