1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📮【Python×Flask】郵便番号検索APIで作るシンプルなWebアプリ

Posted at

はじめに

こんにちは!今回は、PythonのWebフレームワーク「Flask」と日本郵便のAPI(ZipCloud API)を使って、郵便番号から住所を検索するWebアプリを作ってみました!

検索履歴の保存や削除機能もつけて、初心者にも扱いやすい内容になっています。


📮完成イメージ

スクリーンショット 2025-08-08 23.49.10.png

🧰 使用技術・準備

  • Python 3.x
  • Flask
  • requests(API通信用)
  • HTML + CSS(シンプルなフロント)
  • セッション管理(Flask標準)

📦 必要なライブラリのインストール

pip install flask requests

🏗️ アプリの構成

project_folder/
├── app.py
├── templates/
│   └── index.html
├── static/
│   └── style.css

💡 実装のポイント

🔁 郵便番号検索APIの呼び出し(ZipCloud)

api_url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
res = requests.get(api_url)
data = res.json()
  • 7桁の郵便番号を渡すだけで、住所情報をJSON形式で返してくれます。
  • 例:1000001 → 東京都千代田区千代田

🧠 セッションで履歴を保存する工夫

if 'history' not in session:
    session['history'] = []
  • ユーザーごとに履歴をセッションに保存
  • 最大10件まで最新順に表示

🖥️ Flaskアプリ(app.py

from flask import Flask, render_template, request, session, redirect, url_for
import requests
from datetime import datetime

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # セッション管理用

@app.route('/clear_history', methods=['POST'])
def clear_history():
    session['history'] = []
    session.modified = True
    return redirect(url_for('index'))

@app.route('/', methods=['GET', 'POST'])
def index():
    address = None
    error = None
    if 'history' not in session:
        session['history'] = []
    if request.method == 'POST':
        zipcode = request.form.get('zipcode')
        if zipcode:
            api_url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
            res = requests.get(api_url)
            data = res.json()
            if data['status'] == 200 and data['results']:
                result = data['results'][0]
                address = f"{result['address1']}{result['address2']}{result['address3']}"
                session['history'].append({
                    'zipcode': zipcode,
                    'address': address,
                    'time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                })
                session.modified = True
            else:
                error = data.get('message', '該当する住所が見つかりませんでした。')
    history = session.get('history', [])[-10:][::-1]
    return render_template('index.html', address=address, error=error, history=history)

if __name__ == '__main__':
    app.run(debug=True)

🖼️ HTMLテンプレート(templates/index.html

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>郵便番号検索&履歴</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
  </head>
  <body>
    <div class="container">
      <h1>郵便番号検索</h1>
      <form method="post">
        郵便番号: <input type="text" name="zipcode" maxlength="7" required>
        <button type="submit">検索</button>
      </form>
      {% if address %}
        <div class="result">
          <h2>住所結果</h2>
          <p>{{ address }}</p>
        </div>
      {% elif error %}
        <div class="result">
          <p style="color:red;">{{ error }}</p>
        </div>
      {% endif %}
      <div class="history">
        <h2>検索履歴</h2>
        <form method="post" action="{{ url_for('clear_history') }}">
          <button type="submit">履歴をすべて削除</button>
        </form>
        {% if history %}
        <table>
          <tr><th>郵便番号</th><th>住所</th><th>検索日時</th></tr>
          {% for item in history %}
          <tr>
            <td>{{ item.zipcode }}</td>
            <td>{{ item.address }}</td>
            <td>{{ item.time }}</td>
          </tr>
          {% endfor %}
        </table>
        {% else %}
          <p>まだ履歴はありません。</p>
        {% endif %}
      </div>
    </div>
  </body>
</html>

🎨 CSSで見た目も整える(static/style.css

body {
  font-family: 'Roboto', sans-serif;
  background: linear-gradient(120deg, #f6d365 0%, #fda085 100%);
  margin: 0;
  min-height: 100vh;
}
/* 以下略:省略可 */
  • グラデーション背景とカード風のUIで、ポップで見やすいデザインを実現しています。
  • レスポンシブ対応もあり、スマホでも見やすいです。

✅ まとめ

  • FlaskとZipCloud APIを使って、郵便番号から住所を検索するWebアプリを作成
  • セッションを活用して検索履歴を表示・削除
  • HTML・CSSで見た目をカスタマイズ

🙌 最後に

この記事が、Flaskを使ったWebアプリ制作の第一歩になれば幸いです!
質問・コメントなどもお気軽にどうぞ✨

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?