土地利用マップのスクレイピング
WEBページのソースコードから,対象の文字列を取り出す
import re
# 与えられたHTMLコンテンツの例
html_content = """
<div class="mesh" id="M6848-h"
style="left:81.0274372446001%; top:2.43337195828505%; width:3.21074138937536%; height:2.89687137891078%;"
title="6848"></div>
<div class="mesh" id="M6847-h"
style="left:77.9334500875657%; top:2.43337195828505%; width:3.21074138937536%; height:2.89687137891078%;"
title="6847"></div>
<div class="mesh" id="M6842-h"
style="left:62.5802685347344%; top:2.43337195828505%; width:3.21074138937536%; height:2.89687137891078%;"
title="6842"></div>
"""
# 4桁の数字を抽出する
four_digit_numbers = re.findall(r'\b\d{4}\b', html_content)
# 結果を出力する
print("抽出された4桁の数字:", four_digit_numbers)
結果
['6848', '6847', '6842', '6841', '6840', '6748', '6747', '6742', '6741', '6740', '6647', '6646', '6645', '6644', '6643', '6642', '6641', '6546', '6545', '6544', '6543', '6542', '6541', '6540', '6445', '6444', '6443', '6442', '6441', '6440', '6439', '6343', '6342', '6341', '6340', '6339', '6243', '6241', '6240', '6239', '6141', '6140', '6139', '6041', '6040', '6039', '5942', '5941', '5940', '5939', '5841', '5840', '5839', '5741', '5740', '5739', '5738', '5641', '5640', '5639', '5638', '5637', '5636', '5541', '5540', '5539', '5538', '5537', '5536', '5531', '5440', '5439', '5438', '5437', '5436', '5435', '5433', '5432', '5340', '5339', '5338', '5337', '5336', '5335', '5334', '5333', '5332', '5240', '5239', '5238', '5237', '5236', '5235', '5234', '5233', '5232', '5231', '5229', '5139', '5138', '5137', '5136', '5135', '5134', '5133', '5132', '5131', '5130', '5129', '5039', '5038', '5036', '5035', '5034', '5033', '5032', '5031', '5030', '5029', '4939', '4934', '4933', '4932', '4931', '4930', '4929', '4928', '4839', '4831', '4830', '4829', '4828', '4827', '4740', '4739', '4731', '4730', '4729', '4728', '4631', '4630', '4629', '4540', '4531', '4530', '4529', '4440', '4429', '4329', '4328', '4230', '4229', '4228', '4142', '4141', '4140', '4129', '4128', '4042', '4041', '4040', '4028', '4027', '4026', '3942', '3941', '3931', '3928', '3927', '3926', '3924', '3923', '3841', '3831', '3824', '3823', '3741', '3725', '3724', '3653', '3641', '3631', '3624', '3623', '3622', '3036', '3035', '6848', '6847', '6842', '6841', '6840', '6748', '6747', '6742', '6741', '6740', '6647', '6646', '6645', '6644', '6643', '6642', '6641', '6546', '6545', '6544', '6543', '6542', '6541', '6540', '6445', '6444', '6443', '6442', '6441', '6440', '6439', '6343', '6342', '6341', '6340', '6339', '6243', '6241', '6240', '6239', '6141', '6140', '6139', '6041', '6040', '6039', '5942', '5941', '5940', '5939', '5841', '5840', '5839', '5741', '5740', '5739', '5738', '5641', '5640', '5639', '5638', '5637', '5636', '5541', '5540', '5539', '5538', '5537', '5536', '5531', '5440', '5439', '5438', '5437', '5436', '5435', '5433', '5432', '5340', '5339', '5338', '5337', '5336', '5335', '5334', '5333', '5332', '5240', '5239', '5238', '5237', '5236', '5235', '5234', '5233', '5232', '5231', '5229', '5139', '5138', '5137', '5136', '5135', '5134', '5133', '5132', '5131', '5130', '5129', '5039', '5038', '5036', '5035', '5034', '5033', '5032', '5031', '5030', '5029', '4939', '4934', '4933', '4932', '4931', '4930', '4929', '4928', '4839', '4831', '4830', '4829', '4828', '4827', '4740', '4739', '4731', '4730', '4729', '4728', '4631', '4630', '4629', '4540', '4531', '4530', '4529', '4440', '4429', '4329', '4328', '4230', '4229', '4228', '4142', '4141', '4140', '4129', '4128', '4042', '4041', '4040', '4028', '4027', '4026', '3942', '3941', '3931', '3928', '3927', '3926', '3924', '3923', '3841', '3831', '3824', '3823', '3741', '3725', '3724', '3653', '3641', '3631', '3624', '3623', '3622', '3036', '3035']
保存する
指定された文字列を使って特定のURLからデータをダウンロードし、保存するためのPythonスクリプトを以下に示します。このスクリプトは、先ほど抽出した各4桁の数字を使って複数のファイルをダウンロードし、保存します。Pythonの `requests` ライブラリを使用しますが、事前にインストールする必要がある点に注意してください。
import requests
import os
# 事前に抽出した4桁の数字のリスト
four_digit_numbers = ['6848', '6847', '6842']
# 保存するディレクトリを指定(存在しない場合は作成)
save_dir = 'downloaded_files'
if not os.path.exists(save_dir):
os.makedirs(save_dir)
# 各数字に対してURLからデータをダウンロードし保存する
for number in four_digit_numbers:
url = f'https://nlftp.mlit.go.jp/ksj/gml/data/L03-b/L03-b-21/L03-b-21_{number}-tky_GML.zip'
response = requests.get(url)
if response.status_code == 200:
file_path = os.path.join(save_dir, f'L03-b-21_{number}-tky_GML.zip')
with open(file_path, 'wb') as file:
file.write(response.content)
print(f'ファイル {file_path} がダウンロードされ、保存されました。')
else:
print(f'ファイル {number} のダウンロードに失敗しました。ステータスコード: {response.status_code}')
スクリプトの説明:
`requests` を使用して指定されたURLからデータをダウンロードします。
指定されたディレクトリにファイルを保存します。ディレクトリが存在しない場合は作成します。
ダウンロードしたファイルをバイナリモードで保存します。
注意:
`requests` ライブラリが必要です。インストールされていない場合、`pip install requests` を実行してください。
実行前にサーバーのアクセス制限など、URLが有効かどうかを確認してください。
このコードはローカル環境での実行を想定しています。
保存されたZIPファイルを,まとめて解凍する
保存されたZIPファイルをまとめて解凍するために、Pythonの `zipfile` モジュールを使用するスクリプトを以下に示します。このスクリプトは、指定されたディレクトリにあるすべてのZIPファイルを検索し、解凍します。
import zipfile
import os
# ZIPファイルが保存されているディレクトリ
directory = 'downloaded_files'
# ディレクトリ内のすべてのZIPファイルを解凍
for filename in os.listdir(directory):
if filename.endswith('.zip'):
# ZIPファイルのフルパス
file_path = os.path.join(directory, filename)
# ZIPファイルを開く
with zipfile.ZipFile(file_path, 'r') as zip_ref:
# 解凍するディレクトリを指定(同じディレクトリ内に解凍)
extract_path = os.path.join(directory, filename[:-4]) # ファイル名から.zipを除いたディレクトリ名
zip_ref.extractall(extract_path)
print(f'ファイル {filename} が {extract_path} に解凍されました。')
スクリプトの説明:
`zipfile.ZipFile` クラスを使用してZIPファイルを開きます。
`extractall` メソッドでファイルを指定されたディレクトリに解凍します。
解凍される各ファイルは、そのZIPファイルの名前から `.zip` を取り除いたディレクトリに配置されます。
注意:
このコードは、ZIPファイルが保存されているディレクトリに対してのみ実行されます。他のディレクトリにあるZIPファイルを解凍する場合は、ディレクトリのパスを適宜変更してください。
ディレクトリのパスが正しいことを確認し、Pythonスクリプトをそのディレクトリ内または適切な位置で実行してください。
統合する
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
import os
# "土地利用" ディレクトリ内のディレクトリをすべて取得する
dirs = os.listdir("土地利用")
# 統合するGeoDataFrameのリストを初期化
gdf_list = []
# 各ディレクトリに対してシェープファイルを読み込む
total_dirs = len(dirs) # 総ディレクトリ数
for index, d in enumerate(dirs):
file_path = f'土地利用/{d}/' # ファイルパスの構成
gdf_ = gpd.read_file(file_path, encoding="shift-jis")
gdf_list.append(gdf_)
# 進捗度の表示(100%換算で現在の進行状況を出力)
progress = (index + 1) / total_dirs * 100 # 進捗率を計算
print(f'Processing {d}: {progress:.2f}% complete')
# pandas.concat を使用して全てのGeoDataFrameを統合
gdf = pd.concat(gdf_list, ignore_index=True)
_ = gdf[gdf["土地利用種"] == "0700"]
# 軽量化して保存する
gdf_.to_file("土地利用\全国建物用地", driver="ESRI Shapefile", encoding="shift-jis")
# # データをプロットする
_.plot()
plt.show()
より効率的な結合方法
import geopandas as gpd
import pandas as pd
import glob
import os
# SHPファイルが保存されているフォルダを指定
folder_path = '土砂災害\A33-22_00_GML\Shape'
# 指定フォルダ内のすべてのSHPファイルをリストアップ
shp_files = glob.glob(os.path.join(folder_path, '*.shp'))
# 各SHPファイルを読み込み、リストに追加
gdfs = []
for shp in shp_files:
gdf = gpd.read_file(shp)
# ポリゴンのみを保持
gdf = gdf[gdf['geometry'].geom_type == 'Polygon']
gdfs.append(gdf)
# すべてのGeoDataFrameを一つに結合
combined_gdf = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True))
# 結合したGeoDataFrameを新しいSHPファイルとして保存
output_path = os.path.join(folder_path, 'combined_shapefile.shp')
combined_gdf.to_file(output_path)
この記事が気に入ったらサポートをしてみませんか?