工事積算するときに物価資料の平均値から材料の単価を採用しているけど、いちいち検索するのが面倒くさいので、自動化したい。その前段階として、両調査会が公表しているコード一覧をCSVに変換してみた。(最初からcsvで公表してくれると楽なんですがね)
建設物価
収録品目リスト(コードブック)「建設物価4編」のPDFをCSVに変換。
積算資料
建設物価の方とざっくり順番が似ている、コード表(分類順)のPDFを使用。
コード
pyMupdfを使用
建設物価
import fitz
import pandas as pd
import requests
from tqdm import tqdm
pdf_path = 'local-kensetsu.pdf'
csv_path = 'kensetsu-bukka.csv'
data = []
pdf_url = 'https://www.kensetu-bukka.or.jp/wp-content/themes/custom/pdf/service/datafile/unitprice/2024/ken_c.pdf'
r = requests.get(pdf_url, allow_redirects=True)
open(pdf_path, 'wb').write(r.content)
# PDFファイルを開く
pdf_document = fitz.open(pdf_path)
for page_num in tqdm(range(0, len(pdf_document))):
page = pdf_document.load_page(page_num)
tables = page.find_tables()
for table in tables:
for row in table.extract():
data.append(row)
# DataFrameに変換
df = pd.DataFrame(data)
# 改行を削除
df = df.replace("\n", "", regex=True)
# 各ページに含まれていたインデックス行を1番上を除いて削除
df_tmp = df[:1]
contains = df[0].str.contains('帯名称')
df = df.drop(df[contains].index, inplace=True)
df = pd.concat([df_tmp, df])
# CSVファイルに保存
df.to_csv(csv_path, index=False, header=False)
print(f"PDF data has been successfully saved to {csv_path}")
積算資料
import fitz
import pandas as pd
import requests
from tqdm import tqdm
pdf_url = 'https://www.zai-keicho.or.jp/wp-content/uploads/2024/05/denshiban-code1.pdf'
r = requests.get(pdf_url, allow_redirects=True)
open('local_sekisan.pdf', 'wb').write(r.content)
pdf_path = 'local_sekisan.pdf'
csv_path = 'sekisan-shiryo.csv'
data = []
# PDFから値を取り出し
pdf_document = fitz.open(pdf_path)
for page_num in tqdm(range(1, len(pdf_document))):
page = pdf_document.load_page(page_num)
tables = page.find_tables()
for table in tables:
for row in table.extract():
data.append(row)
df = pd.DataFrame(data)
# 改行を取り除く
df = df.replace("\n", "", regex=True)
# 上の値を使って欠損値を埋める
df = df.fillna(method='ffill')
# 各ページに含まれていたインデックス行を1番上を除いて削除
df_tmp = df[:1]
contains = df[0].str.contains('分類2名称')
df.drop(df[contains].index, inplace=True)
df = pd.concat([df_tmp, df])
df.to_csv(csv_path, index=False, header=False)