[PYTHON] Data wrangling (pdfplumber) PDF sur l'épidémie de grippe par le ministère de la Santé, du Travail et du Bien-être social

Créé Données PDF sur la situation de l'épidémie de grippe du ministère de la Santé, du Travail et du Bien-être social avec pdfplumber

C'est facile car vous pouvez vérifier la position du caractère avec des caractères et spécifier la plage de recadrage.

with pdfplumber.open("data.pdf") as pdf:

    p1 = pdf.pages[1]

    #Vérifiez la position du texte
    p1.chars

    #Obtenir du texte avec recadrage
    week_crop = p1.within_bbox((0, 90, p1.width, 105))
    s = week_crop.extract_text()

programme

import csv
import datetime
import pathlib
import re
from urllib.parse import urljoin

import pdfplumber
import pandas as pd
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

url = "https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/kenkou_iryou/kenkou/kekkaku-kansenshou01/houdou_00008.html"

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")

d1 = []
d2 = []

for i in soup.select('ul.m-listLink > li > a[href$=".pdf"]')[::-1]:

    text = i.get_text(strip=True)

    t = re.match("(\d{4})An(\d{1,2})Lune(\d{1,2})journée", text)

    #Date du communiqué de presse

    if t:
        year, month, day = map(int, t.groups())
        dt_date = datetime.date(year, month, day)
    else:
        dt_date = datetime.date.today()

    #fichier PDF

    link = urljoin(url, i.get("href"))

    p = fetch_file(link)

    with pdfplumber.open(p) as pdf:

        p1 = pdf.pages[1]

        #Obtenir du texte avec recadrage
        week_crop = p1.within_bbox((0, 90, p1.width, 105))
        s = week_crop.extract_text()

        m = re.search("(\d{4})An(\d{1,2})la semaine\((\d{1,2})Lune(\d{1,2})Soleil ~(\d{1,2})Lune(\d{1,2})journée\)", s)

        if m:
            s_year, s_week, s_month, s_day, e_month, e_day = map(int, m.groups())

            dt_start = datetime.date(s_year, s_month, s_day)
            dt_end = datetime.date(s_year, e_month, e_day)

            if dt_start > dt_end:
                dt_end = datetime.date(s_year + 1, e_month, e_day)

            table = p1.extract_table()

            df_tmp = pd.DataFrame(
                table[2:], columns=["Préfectures", "Nombre de rapports", "Par point fixe"]
            ).set_index("Préfectures")

            df_tmp.index = df_tmp.index.map(lambda s: "".join(s.split()))

            df_tmp = df_tmp.mask(df_tmp == "-")
            df_tmp["Nombre de rapports"] = df_tmp["Nombre de rapports"].str.replace(",", "").astype(float).astype("Int64")
            df_tmp["Par point fixe"] = df_tmp["Par point fixe"].astype(float)

            df_tmp.loc["An"] = s_year
            df_tmp.loc["la semaine"] = s_week
            df_tmp.loc["date de début"] = dt_start
            df_tmp.loc["Date de fin"] = dt_end

            s1 = df_tmp["Nombre de rapports"]
            s1.name = dt_date
            d1.append(s1)

            s2 = df_tmp["Par point fixe"]
            s2.name = dt_date
            d2.append(s2)

df1 = pd.concat(d1, axis=1, sort=False).T.astype({"An": int, "la semaine": int})
df2 = pd.concat(d2, axis=1, sort=False).T.astype({"An": int, "la semaine": int})

df3 = df1.join(df2, rsuffix="(Par point fixe)")

df = df3.reindex(
    columns=[
        "An",
        "la semaine",
        "date de début",
        "Date de fin",
        "Hokkaido",
        "Hokkaido (par point fixe)",
        "Préfecture d'Aomori",
        "Préfecture d'Aomori (par point fixe)",
        "Préfecture d'Iwate",
        "Préfecture d'Iwate (par point fixe)",
        "Préfecture de Miyagi",
        "Préfecture de Miyagi (par point fixe)",
        "Akita",
        "Préfecture d'Akita (par point fixe)",
        "Préfecture de Yamagata",
        "Préfecture de Yamagata (par point fixe)",
        "Préfecture de Fukushima",
        "Préfecture de Fukushima (par point fixe)",
        "Préfecture d'Ibaraki",
        "Préfecture d'Ibaraki (par point fixe)",
        "Préfecture de Tochigi",
        "Préfecture de Tochigi (par point fixe)",
        "Préfecture de Gunma",
        "Préfecture de Gunma (par point fixe)",
        "Saitama",
        "Préfecture de Saitama (par point fixe)",
        "Préfecture de Chiba",
        "Préfecture de Chiba (par point fixe)",
        "Tokyo",
        "Tokyo (par point fixe)",
        "Préfecture de Kanagawa",
        "Préfecture de Kanagawa (par point fixe)",
        "Préfecture de Niigata",
        "Préfecture de Niigata (par point fixe)",
        "Préfecture de Toyama",
        "Préfecture de Toyama (par point fixe)",
        "Préfecture d'Ishikawa",
        "Préfecture d'Ishikawa (par point fixe)",
        "Préfecture de Fukui",
        "Préfecture de Fukui (par point fixe)",
        "Préfecture de Yamanashi",
        "Préfecture de Yamanashi (par point fixe)",
        "Préfecture de Nagano",
        "Préfecture de Nagano (par point fixe)",
        "Préfecture de Gifu",
        "Préfecture de Gifu (par point fixe)",
        "Préfecture de Shizuoka",
        "Préfecture de Shizuoka (par point fixe)",
        "Préfecture d'Aichi",
        "Préfecture d'Aichi (par point fixe)",
        "Préfecture de Mie",
        "Préfecture de Mie (par point fixe)",
        "Préfecture de Shiga",
        "Préfecture de Shiga (par point fixe)",
        "Kyoto",
        "Kyoto (par point fixe)",
        "Préfecture d'Osaka",
        "Osaka (par point fixe)",
        "Préfecture de Hyogo",
        "Préfecture de Hyogo (par point fixe)",
        "Préfecture de Nara",
        "Préfecture de Nara (par point fixe)",
        "Préfecture de Wakayama",
        "Préfecture de Wakayama (par point fixe)",
        "Préfecture de Tottori",
        "Préfecture de Tottori (par point fixe)",
        "Préfecture de Shimane",
        "Préfecture de Shimane (par point fixe)",
        "Préfecture d'Okayama",
        "Préfecture d'Okayama (par point fixe)",
        "Préfecture d'Hiroshima",
        "Préfecture d'Hiroshima (par point fixe)",
        "Préfecture de Yamaguchi",
        "Préfecture de Yamaguchi (par point fixe)",
        "Préfecture de Tokushima",
        "Préfecture de Tokushima (par point fixe)",
        "Préfecture de Kagawa",
        "Préfecture de Kagawa (par point fixe)",
        "Préfecture d'Ehime",
        "Préfecture d'Ehime (par point fixe)",
        "Préfecture de Kochi",
        "Préfecture de Kochi (par point fixe)",
        "Préfecture de Fukuoka",
        "Préfecture de Fukuoka (par point fixe)",
        "Préfecture de Saga",
        "Préfecture de Saga (par point fixe)",
        "Préfecture de Nagasaki",
        "Préfecture de Nagasaki (par point fixe)",
        "Préfecture de Kumamoto",
        "Préfecture de Kumamoto (par point fixe)",
        "Préfecture d'Oita",
        "Préfecture d'Oita (par point fixe)",
        "Préfecture de Miyazaki",
        "Préfecture de Miyazaki (par point fixe)",
        "Préfecture de Kagoshima",
        "Préfecture de Kagoshima (par point fixe)",
        "Préfecture d'Okinawa",
        "Préfecture d'Okinawa (par point fixe)",
        "Nombre total",
        "Nombre total (par point fixe)",
        "Synchronisé l'année dernière (total)",
        "Synchronisé l'année dernière (nombre total) (par point fixe)",
    ]
)

df1.to_csv(
    "influ_count.csv", index=False, quoting=csv.QUOTE_NONNUMERIC, encoding="utf_8_sig",
)

df2.to_csv(
    "influ_point.csv", index=False, quoting=csv.QUOTE_NONNUMERIC, encoding="utf_8_sig",
)

df.to_csv(
    "influ_all.csv", index=False, quoting=csv.QUOTE_NONNUMERIC, encoding="utf_8_sig", na_rep="-",
)

Recommended Posts

Data wrangling (pdfplumber) PDF sur l'épidémie de grippe par le ministère de la Santé, du Travail et du Bien-être social
Data Langling PDF sur l'épidémie de grippe par le ministère de la Santé, du Travail et du Bien-être social
Nettoyage des données des données ouvertes de la situation d'occurrence du ministère de la Santé, du Travail et des Affaires sociales
Scraping PDF du statut des personnes testées positives dans chaque préfecture du ministère de la Santé, du Travail et du Bien-être social
Scraping PDF de la liste nationale des salaires minimums par région du ministère de la Santé, du Travail et du Bien-être social
[Python] Lisez automatiquement les informations par préfecture du nouveau virus corona du PDF du ministère de la Santé, du Travail et du Bien-être social et écrivez-les dans un tableur ou Excel.
Histoire de l'analyse d'image du fichier PDF et de l'extraction de données