Flaskでサイトマップ(sitemap.xml)を設置する方法
2024年11月26日

こんにちは!
今回の記事では、Flaskでサイトマップ(sitemap.xml)を設置する方法について解説します。
ウェブサイトを運営する上で、サイトマップは重要な要素の一つです。検索エンジンにサイトの構造を効率的に伝えることができ、SEO対策の観点からも欠かせません。
本記事では、PythonのWebフレームワーク「Flask」を使ってサイトマップを生成し、公開する方法を解説します。
Flaskでサイトマップを実装する手順
ここからは、Flaskでサイトマップを実装する手順について解説します。
まず前提として、データベースなどのデータから動的にページを生成するアプリケーションを想定します。例えば、ブログやECサイトなどです。
記事データを取得して、動的にサイトマップを生成する手順を解説します。
データベースの構造
まず、データベースの構造を見ていきます。記事データを格納するテーブルを作成します。
以下のようにmodels.pyを記述します。
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100))
updated_at = db.Column(db.DateTime)
app.pyの記述
続いて、app.pyの記述をします。以下のようにルートを実装します。
from flask import Flask, request, Response, render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
# Flaskアプリケーションの初期化
app = Flask(__name__)
# データベースの設定
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db' # SQLiteを使用
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# データベース初期化
db = SQLAlchemy(app)
# モデルのインポート
from models import Article
# サイトマップのルート定義
@app.route('/sitemap.xml', methods=['GET'])
def sitemap():
# ベースURLを取得
base_url = request.host_url.rstrip('/')
# 固定ページ
pages = [
{'loc': f"{base_url}/", 'lastmod': datetime.now().strftime('%Y-%m-%d')},
{'loc': f"{base_url}/about", 'lastmod': datetime.now().strftime('%Y-%m-%d')},
]
# データベースから記事を取得
articles = Article.query.all()
for article in articles:
pages.append({
'loc': f"{base_url}/articles/{article.id}",
'lastmod': article.updated_at.strftime('%Y-%m-%d')
})
# サイトマップをテンプレートから生成
sitemap_xml = render_template('sitemap_template.xml', pages=pages)
return Response(sitemap_xml, content_type='application/xml')
if __name__ == '__main__':
# アプリケーションの起動
app.run(debug=True)
上記では、固定ページの/(ルート)と/aboutと記事のページをサイトマップとして登録しています。
/sitemap.xmlへアクセスしたら、サイトマップを生成するようなコードになっています。コードの解説は後ほど行います。
テンプレートの実装
Flaskでは、テンプレートエンジン(Jinja2)を使用して動的にXMLを生成します。以下のようなテンプレートファイルを作成します。templates/sitemap_template.xmlファイルを作成します。
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for page in pages %}
<url>
<loc>{{ page.loc }}</loc>
<lastmod>{{ page.lastmod }}</lastmod>
</url>
{% endfor %}
</urlset>
上記のコードは、サイト内のページリスト(pages)をループで処理し、各ページの情報をXML形式で記述します。
<url>タグでは、各ページの情報を記述します。その子要素として、<loc>タグと<lastmod>タグがあります。
<loc>タグには、ページのURLを記述します。<lastmod>タグには、ページの最終更新日時を記述します。検索エンジンはこの情報を使用して、インデックスの更新タイミングを決定します。
このようにサイトマップの実装を行います。
app.pyの解説
続いて、サイトマップの実装部分(app.py)の解説を行います。
app.pyの以下の部分で、サイトマップを生成する処理を行っています。
# サイトマップのルート定義
@app.route('/sitemap.xml', methods=['GET'])
def sitemap():
# ベースURLを取得
base_url = request.host_url.rstrip('/')
# 固定ページ
pages = [
{'loc': f"{base_url}/", 'lastmod': datetime.now().strftime('%Y-%m-%d')},
{'loc': f"{base_url}/about", 'lastmod': datetime.now().strftime('%Y-%m-%d')},
]
# データベースから記事を取得
articles = Article.query.all()
for article in articles:
pages.append({
'loc': f"{base_url}/articles/{article.id}",
'lastmod': article.updated_at.strftime('%Y-%m-%d')
})
# サイトマップをテンプレートから生成
sitemap_xml = render_template('sitemap_template.xml', pages=pages)
return Response(sitemap_xml, content_type='application/xml')
ベースURLの取得
まず、以下のコードでベースURLを取得します。
base_url = request.host_url.rstrip('/')
request.host_urlで、現在のリクエストが発生したホストのURLを取得します。例えば、http://127.0.0.1:5000/といったURLです。
.rstrip(‘/’)を使って、末尾の/を削除しています。
これにより、http://127.0.0.1:5000/ → http://127.0.0.1:5000 のように末尾の/がなくなります。
固定ページの定義
続いて、固定ページの定義をします。
pages = [
{'loc': f"{base_url}/", 'lastmod': datetime.now().strftime('%Y-%m-%d')},
{'loc': f"{base_url}/about", 'lastmod': datetime.now().strftime('%Y-%m-%d')},
]
これは、動的に生成されないページです。サイト内で常に存在するページをリストで定義します。
動的ページの追加
続いて、データベース内のArticleテーブルからすべての記事を取得し、URLを生成しています。これは、自身の環境に合わせて変更してください。
articles = Article.query.all()
for article in articles:
pages.append({
'loc': f"{base_url}/articles/{article.id}",
'lastmod': article.updated_at.strftime('%Y-%m-%d')
})
サイトマップXMLの生成
最後に、サイトマップを生成し、レスポンスとして返すように設定します。
# サイトマップをテンプレートから生成
sitemap_xml = render_template('sitemap_template.xml', pages=pages)
return Response(sitemap_xml, content_type='application/xml')
Flaskのレスポンスクラスで、生成されたXMLをHTTPレスポンスとして返します。レスポンスヘッダーのContent-Typeをapplication/xmlに設定しています。
まとめ
本記事では、Flaskを使ったサイトマップ(sitemap.xml)の設置方法を詳しく解説しました。サイトマップは、検索エンジンにサイトの構造を効率的に伝え、SEO対策を強化する重要な役割を担います。
この記事の手法を使えば、静的なページだけでなく、データベースから動的に生成されるページも簡単にサイトマップに含めることが可能です。
具体的には、Flaskの@app.routeでサイトマップ用のエンドポイントを作成し、固定ページやデータベースのデータを動的に取得して、ページ情報をリストに格納します。その後、Jinja2テンプレートを用いて、XML形式のサイトマップを生成し、クライアントにレスポンスとして返します。
この記事で紹介したコードは、ブログやECサイトなど、動的コンテンツが多いウェブサイトに適用できます。サイトマップの内容を簡単に更新できるため、効率的な運用が可能です。また、Flaskを使用しているプロジェクトであれば、柔軟にカスタマイズできます。
サイトマップを設置することで、検索エンジンがウェブサイトを正確にクロールできるようになり、SEO効果を最大化できます。ぜひ本記事の手法を参考に、自分のプロジェクトに取り入れてみてください。
ここまでお読みいただきありがとうございました!
Pythonの基礎から応用まで学べる
Python WebAcademy
Python WebAcademyでは、Pythonの基礎からアーキテクチャなどの応用的な内容まで幅広く学べます。また、ブラウザ上で直接Pythonコードを試すことができ、実践的なスキルを身につけることが可能です。

インフラの学習はInfraAcademy

おすすめの記事









