はじめに
お疲れさまです🍵
今回は、前回の記事の続きで、郵便局のデータを取得・活用するスクリプトを作成していきます。
よろしくお願いいたします!

郵便番号から住所を取得する
以下のコードでは、MySQLに保存された郵便局データベースを使って、7桁の郵便番号から対応する住所を取得します。
import mysql.connector*
def get_address_by_zip(zip_code):
# 郵便番号の形式チェック
if len(zip_code) != 7 or not zip_code.isdigit():
return "郵便番号は7桁の数字で入力してください。"
try:
# データベースに接続
conn = mysql.connector.connect(
host='***', #データベースが動いているサーバーのアドレス
user='***', #ログインユーザー名
password='***', #ユーザー名に対応するパスワード
database='***, #接続するデータベース名
connection_timeout=5 #5秒以内に接続できなければタイムアウトとしてエラーを吐く
)
cursor = conn.cursor()
# 郵便番号に一致する住所を検索
query = """
SELECT kana1, kana2, kana3, name1, name2, name3
FROM post
WHERE post_code = %s
"""
cursor.execute(query, (zip_code,))
results = cursor.fetchall()
if results:
# かな・漢字の住所を結合して表示
kana = " ".join([part if part is not None else "" for part in results[0][:3]])
name = " ".join([part if part is not None else "" for part in results[0][3:]])
return f"住所(かな): {kana.strip()}\n住所(漢字): {name.strip()}"
else:
return "該当する住所が見つかりませんでした。"
except mysql.connector.Error as err:
return f"データベースエラー: {err}"
finally:
# リソースの後始末
if 'cursor' in locals():
cursor.close()
if 'conn' in locals():
conn.close()
# ユーザーから郵便番号を受け取って検索
zip_code = input("郵便番号(7桁)を入力してください: ").strip()
address = get_address_by_zip(zip_code)
print(address)
関数の説明
この関数では、ユーザーが入力した郵便番号をもとに、対応する住所をデータベースから取得しています。
まず最初に、入力された郵便番号の形式をチェックします。
len(zip_code) != 7
は、郵便番号が7文字じゃない場合はアウトです。
日本の郵便番号は7桁なので、このチェックが必要になります。
not zip_code.isdigit()
ここでは、郵便番号に数字以外の文字が含まれていた場合もエラーにします。
(例)「160-0011」や「abc1234」など
続いて、データベースとMYSQLを接続します。
mysql.connector.connect()
でPython からデータベースへ接続しています。
接続エラーをハンドリングするため、try-catchのブロック内に書いています。
この接続がうまくいけば、次の処理でデータベースから郵便番号を使って、住所データを検索することができます。
逆に、サーバーが落ちていたり、パスワードが間違っていたりすると、この時点でエラーになります。
次に、カーソルを作成します。
cursor = conn.cursor()
カーソルは、プログラムとデータベースと間でやりとりを行うためのものです。
今回の場合は、クエリを実行したり、実行結果を受け取ったりします。
ここでは、郵便番号に一致する住所を検索するSQLが書かれています。
# 郵便番号に一致する住所を検索
query = """
SELECT kana1, kana2, kana3, name1, name2, name3
FROM post
WHERE post_code = %s
"""
MySQLに送るSELECT文を準備しています。
クエリ文は、今回は分かりやすさを優先してコード内にハードコーディングしています。
(本格的なアプリ開発では、設定ファイルや別管理にすることが多い点だけ少し注意です!)
カラムの意味は、都道府県/市区町村/町名です。
kana1, kana2, kana3 は住所のかな表記、
name1, name2, name3 は住所の漢字表記になってます。
WHERE post_code = %s
は、検索条件です。
post_code(郵便番号)が指定された値(後で渡す値)と一致するデータだけを取得します。
%s
はプレースホルダーです。
悪意のあるデータによる攻撃を防ぐために、値を後から別で渡し、クエリと値を分けて実行します。
続いて、クエリ実行と結果の取得します。
cursor.execute(query, (zip_code,))
queryに書いたSQL文をDBに送って実行します。
(zip_code,) は %s に当てはめる値。タプルで渡す必要があるのでカンマ付きにしています。
※タプル(tuple)とはデータ型のひとつで、複数の値をまとめて持てます。
results = cursor.fetchall()
検索結果が複数行あったときのために、全部まとめて取り出しています。
resultsはリスト形式で、中身はタプルの集まりです。
たとえばこんな感じになります。
[('トウキョウト', 'シンジュクク', 'シンジュク', '東京都', '新宿区', '新宿')]
郵便番号で住所を取り出したときのこの行:
('トウキョウト', 'シンジュクク', 'シンジュク', '東京都', '新宿区', '新宿')
1行分の住所データが1つのタプルにまとめられてます。
if results:
# かな・漢字の住所を結合して表示
kana = " ".join([part if part is not None else "" for part in results[0][:3]])
name = " ".join([part if part is not None else "" for part in results[0][3:]])
return f"住所(かな): {kana.strip()}\n住所(漢字): {name.strip()}"
else:
return "該当する住所が見つかりませんでした。"
ここでは、DBから取得した検索結果を整えて返します。
条件文では、検索結果が「存在するかどうか」をチェックします。
results[0] には、以下のような値が入っているとします:
('トウキョウト', 'シンジュクク', 'シンジュク', '東京都', '新宿区', '新宿')
これをそれぞれ、かなの住所と漢字の住所に分けて整形します。
kana = " ".join([part if part is not None else "" for part in results[0][:3]])
name = " ".join([part if part is not None else "" for part in results[0][3:]])
[:3] で最初の3つ(かな)を、[3:] で後ろの3つ(漢字)を取り出しています。
None の場合は空文字 "" に置き換えて、エラーにならないようにしています。
" ".join(...) で、それらのパーツをスペースでつなげています。
return f"住所(かな): {kana.strip()}\n住所(漢字): {name.strip()}"
住所をひらがなと漢字でフォーマットして返します。
そして、次の部分:
else:
return "該当する住所が見つかりませんでした。"
もし該当する住所が見つからなかった場合に「該当する住所が見つかりませんでした。」というメッセージを返します。
except mysql.connector.Error as err:
return f"データベースエラー: {err}"
MySQLの接続中にエラーが発生した場合にエラーをキャッチし、そのエラーメッセージを返します。
return f"データベースエラー: {err}"
これにより、MySQLのエラーが発生した際に、エラーメッセージの内容が表示されます。
pythonコピーする編集するfinally:
# リソースの後始末
if 'cursor' in locals():
cursor.close()
if 'conn' in locals():
conn.close()
finallyブロックは、tryブロックとexceptブロックの後に必ず実行される部分で、
リソースの掃除や不要なデータの削除を行います。
cursor.close()
は、データベース操作を終了した後、カーソルを閉じます。
conn.close()
はデータベースの接続を閉じて、リソースを解放します。
if 'cursor' in locals()if 'conn' in locals()
は、それぞれカーソルとデータベースが定義されている場合にのみ、閉じる処理を行います。
そうすることで、未定義の変数に対して、エラーが発生しないようにしています。
zip_code = input("郵便番号(7桁)を入力してください: ").strip()
は、ユーザーに郵便番号を入力してもらい、入力された内容を整えて、変数 zip_code に格納します。
input()はユーザーからの入力を受け取ります。
.strip() は文字列の先頭と末尾の余分な空白文字を取り除きます。
address = get_address_by_zip(zip_code)print(address)
郵便番号に基づいて住所を取得します。
get_address_by_zip(zip_code)では、関数get_address_by_zip() を呼び出しています。
引数として、先ほど取得した郵便番号 zip_code を渡しています。
get_address_by_zip() が返す住所の結果は、変数 address に格納されます。
この後、print(address)で、変数addressに格納された住所を表示します。
まとめ
今回は、PythonとMySQLを使って、郵便番号から住所を検索しました。
ありがとうございました!
コメント