Python Flask を使って URL 短縮機を作成する

PythonPythonBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

このプロジェクトでは、PythonとFlaskを使ってURLショートナーを作成する方法を学びます。URLショートナーは、長いURLを取り、より短く、管理しやすいURLに変換するツールです。これは、ソーシャルメディアやメールでリンクを共有する際に便利であり、長いURLをユーザーにとって使いやすくすることもできます。

👀 プレビュー

URLショートナーのインターフェイスのプレビュー

🎯 タスク

このプロジェクトでは、以下を学びます。

  • プロジェクトフォルダをセットアップし、URLショートナーに必要なファイルを作成する方法。
  • 元のURLとそれに対応する短縮URLを格納するためのSQLiteデータベースをセットアップする方法。
  • ランダムな文字を使って短いURLを生成する方法。
  • ユーザーが短縮するURLを送信し、短縮URLを表示するインデックスページを作成する方法。
  • ユーザーが短縮URLを入力したときに元のURLにリダイレクトする方法。
  • 短縮されたすべてのURLを表示する履歴ページを作成する方法。
  • プロジェクトを実行し、ウェブブラウザでテストする方法。

🏆 成果

このプロジェクトを完了すると、以下のことができるようになります。

  • Flaskプロジェクトをセットアップし、必要なファイルを作成する方法を理解する。
  • SQLiteを使ってデータベースを作成し、クエリを実行する。
  • 短いURLにランダムな文字を生成する。
  • HTMLテンプレートを開発し、基本テンプレートを拡張する。
  • Flaskを使ってフォームの送信を処理し、動的なコンテンツを表示する。
  • ユーザー入力に基づいたURLのリダイレクトを実装する。

プロジェクトファイルの作成

始めるには、プロジェクトフォルダを作成し、以下のファイルを追加します。

  • app.py:このファイルには、URLショートナーのすべてのコードが含まれます。
  • templates/index.html:このファイルには、ウェブサイトのインデックスページのHTMLコードが含まれます。
  • templates/history.html:このファイルには、ウェブサイトの履歴ページのHTMLコードが含まれます。
  • templates/base.html:このファイルには、index.htmlhistory.htmlの両方で使用される基本的なHTMLコードが含まれます。
cd ~/project
touch app.py
mkdir templates
touch templates/index.html templates/history.html templates/base.html

データベースのセットアップ

私たちのURLショートナーには、元のURLとそれに対応する短縮URLを格納するためのデータベースが必要です。私たちは、軽量で使いやすいデータベース管理システムであるSQLiteをデータベースとして使用します。

データベースをセットアップするには、まずapp.pyに必要なモジュールをインポートする必要があります。

## app.py
from flask import Flask, render_template, request, redirect
import string
import random
import sqlite3

次に、SQLiteデータベースに接続し、カーソルオブジェクトを作成する必要があります。

## SQLiteデータベースに接続
conn = sqlite3.connect("urls.db", check_same_thread=False)
db = conn.cursor()

その後、URLを格納するためのデータベース内のテーブルを作成できます。

## URLsテーブルが存在しない場合は作成
db.execute(
    """CREATE TABLE IF NOT EXISTS urls
              (id INTEGER PRIMARY KEY AUTOINCREMENT,
               original_url TEXT NOT NULL,
               short_url TEXT NOT NULL,
               created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"""
)
conn.commit()
✨ 解答を確認して練習

短縮URLの生成

短縮URLを生成するには、ランダムな文字と数字の組み合わせを使用します。これは、Pythonのstringrandomモジュールを使用して達成できます。6文字のランダムな文字列を返すgenerate_short_url()という関数を作成します。

def generate_short_url():
    characters = string.ascii_letters + string.digits
    short_url = "".join(random.choice(characters) for _ in range(6))
    return short_url
✨ 解答を確認して練習

インデックスページの作成

私たちのウェブサイトのインデックスページでは、ユーザーが短縮するURLを送信できるようになります。また、生成されたら短縮URLも表示されます。このページのHTMLコードはtemplates/index.htmlにあります。

まず、base.htmlテンプレートを拡張し、ユーザーがURLを送信するためのフォームを作成する必要があります。

{% extends "base.html" %} {% block content %}
<div class="text-center">
  <h1 class="text-3xl font-bold text-gray-900 mb-8">Shorten Your URL</h1>
  <form action="/" method="POST" class="w-full max-w-sm mx-auto">
    <div
      class="flex items-center border-2 border-blue-500 rounded overflow-hidden"
    >
      <input
        type="text"
        name="original_url"
        placeholder="Enter URL"
        class="appearance-none bg-transparent border-none w-full text-gray-700 py-2 px-4 leading-tight focus:outline-none"
      />
      <button
        type="submit"
        class="bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded-r focus:outline-none"
      >
        Shorten
      </button>
    </div>
  </form>
  {% if short_url %}
  <div class="mt-4">
    <p class="text-lg text-gray-700">
      Short URL:
      <a href="{{ request.host_url }}{{ short_url }}" class="text-blue-500"
        >{{ request.host_url }}{{ short_url }}</a
      >
    </p>
  </div>
  {% endif %}
</div>
{% endblock %}

index.htmlでは、ユーザーがURLを入力するための単一の入力フィールドを持つフォームがあります。フォームは同じページに送信されるため、action属性を/に設定します。また、method属性をPOSTに設定して、フォームデータを要求ボディに送信するようにします。

次に、templates/base.htmlを追加します。

<!doctype html>
<html>
  <head>
    <title>URL Shortener</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <nav class="p-6 bg-white flex justify-between items-center">
      <a href="/" class="text-2xl font-bold text-gray-900">URL Shortener</a>
      <div>
        <a href="/" class="text-gray-800 mr-6">Home</a>
        <a href="/history" class="text-gray-800">History</a>
      </div>
    </nav>
    <main class="container mx-auto max-w-xl pt-8 min-h-screen">
      {% block content %} {% endblock %}
    </main>
  </body>
</html>

base.htmlでは、ページの上部にホームページと履歴ページへのリンクがあるナビゲーションバーがあります。また、各ページのコンテンツを含むmain要素もあります。contentブロックには、各ページのコンテンツが挿入されます。

また、フォームの送信を処理し、短縮URLを生成するために必要なコードをapp.pyに追加する必要があります。

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        original_url = request.form["original_url"]
        short_url = generate_short_url()

        ## 元のURLと短縮URLをデータベースに挿入
        db.execute(
            "INSERT INTO urls (original_url, short_url) VALUES (?,?)",
            (original_url, short_url),
        )
        conn.commit()

        return render_template("index.html", short_url=short_url)

    return render_template("index.html")

index()では、要求メソッドがPOSTであるかどうかを確認します。もしそうなら、フォームデータから元のURLを取得し、短縮URLを生成します。その後、元のURLと短縮URLをデータベースに挿入し、短縮URL付きでindex.htmlテンプレートをレンダリングします。

✨ 解答を確認して練習

元のURLにリダイレクトする

ユーザーが短縮URLを入力したとき、対応する元のURLにリダイレクトしたいと思います。これを行うには、短縮URLに基づいてデータベースから元のURLを取得する関数を作成する必要があります。

@app.route("/<short_url>")
def redirect_to_url(short_url):
    ## 短縮URLに基づいてデータベースから元のURLを取得
    db.execute("SELECT original_url FROM urls WHERE short_url=?", (short_url,))
    result = db.fetchone()

    if result:
        original_url = result[0]
        return redirect(original_url)

    return render_template("index.html")
✨ 解答を確認して練習

履歴ページの作成

履歴ページでは、短縮されたすべてのURLと、その元のURLと追加日付が表示されます。このページのHTMLコードはtemplates/history.htmlにあります。

まず、base.htmlテンプレートを拡張し、URLを表示するためのテーブルを追加する必要があります。

{% extends "base.html" %} {% block content %}
<div class="w-full overflow-x-auto">
  <table class="w-full bg-white rounded shadow overflow-hidden">
    <thead class="bg-gray-200">
      <tr>
        <th
          class="text-left py-3 px-4 uppercase font-semibold text-sm text-gray-700"
        >
          元のURL
        </th>
        <th
          class="text-left py-3 px-4 uppercase font-semibold text-sm text-gray-700"
        >
          短縮URL
        </th>
        <th
          class="text-left py-3 px-4 uppercase font-semibold text-sm text-gray-700"
        >
          日付
        </th>
      </tr>
    </thead>
    <tbody>
      {% for result in results %}
      <tr class="hover:bg-gray-100">
        <td class="border-t">
          <p class="py-3 px-4">{{ result[0] }}</p>
        </td>
        <td class="border-t">
          <a
            href="{{ request.host_url }}{{ result[1] }}"
            class="py-3 px-4 text-blue-500 hover:text-blue-700"
            >{{ request.host_url }}{{ result[1] }}</a
          >
        </td>
        <td class="border-t">
          <p class="py-3 px-4">{{ result[2] }}</p>
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</div>
{% endblock %}

また、app.pyに必要なコードを追加して、データベースからURLを取得し、テンプレートに渡す必要があります。

@app.route("/history")
def history():
    ## データベースからすべてのURLを取得し、最新のものから順に並べる
    db.execute(
        "SELECT original_url, short_url, created_at FROM urls ORDER BY created_at DESC"
    )
    results = db.fetchall()
    return render_template("history.html", results=results)
✨ 解答を確認して練習

プロジェクトの実行

app.pyの末尾に以下のコードを追加します。

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=8080)

モジュールをインストールしたら、ターミナルでpython app.pyを実行することでプロジェクトを実行できます。これによりFlask開発サーバーが起動し、http://localhost:8080でウェブサイトにアクセスできるようになります。

8080タブに切り替えてページを更新します。以下のように表示されるはずです。

Flask server running successfully
✨ 解答を確認して練習

まとめ

このプロジェクトでは、PythonとFlaskを使ってURL短縮機を作成する方法を学びました。まず、必要なプロジェクトファイルとデータベースをセットアップし、次に短縮URLを生成し、フォーム送信を処理する関数を作成しました。また、データベースからURLを取得して表示する方法も学びました。このプロジェクトを通じて、あなたは自分だけのURL短縮機を作成し、好みに合わせてカスタマイズすることができるようになりました。