bokumin.org

Github

サイトマップ(Sitemap)を秒速生成する

create sitemaps in the blink

 


これまでNode.jsやPythonのツールでサイトマップを作成していましたが、ネットワーク経由のクロールは時間がかかるし、リダイレクトエラーも頻発するし・・自作すれば早いと思いつつも面倒で後回しにしていたのですが、先週の休日を使ってようやく作成しました。ローカルで動作し、システム標準ツール(mariadb、grep、sed)のみで実行可能なようにシンプルに作りました。

 

 

cat make-sitemap.sh 
#!/bin/bash

OUTPUT_FILE="/srv/www/htdocs/sitemap.xml"
#OUTPUT_FILE="test_sitemap.xml"
WEBROOT="/srv/www/htdocs"
DOMAIN="https://bokumin.org"
WP_CONFIG="/srv/www/htdocs/blog/wp-config.php"

DB_NAME=$(grep "DB_NAME" "$WP_CONFIG" | cut -d "'" -f 4)
DB_USER=$(grep "DB_USER" "$WP_CONFIG" | cut -d "'" -f 4)
DB_PASSWORD=$(grep "DB_PASSWORD" "$WP_CONFIG" | cut -d "'" -f 4)
DB_HOST=$(grep "DB_HOST" "$WP_CONFIG" | cut -d "'" -f 4)
TABLE_PREFIX=$(grep '$table_prefix' "$WP_CONFIG" | cut -d "'" -f 2)

cat > "$OUTPUT_FILE" << 'EOF'
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
        http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
EOF

process_url() {
    local path="$1"
    local full_path="$WEBROOT$path"
    
    if [[ -f "$full_path" ]]; then
        lastmod=$(date -r "$full_path" +%Y-%m-%d)
    elif [[ -d "$full_path" ]]; then
        lastmod=$(date -r "$full_path" +%Y-%m-%d)
    else
        return
    fi
    
    cat >> "$OUTPUT_FILE" << EOF
  <url>
    <loc>$DOMAIN$path</loc>
    <lastmod>$lastmod</lastmod>
  </url>
EOF
}

process_url "/"
process_url "/art-works/"
process_url "/gpg-public-key.txt"
process_url "/others/"
process_url "/spam-check/"
process_url "/amedas-dashboard/"
process_url "/blog/"

mariadb -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" -D "$DB_NAME" -N -e "
SELECT 
    CONCAT('/blog/', DATE_FORMAT(post_date, '%Y/%m/%d'), '/', post_name, '/'),
    DATE_FORMAT(post_date, '%Y-%m-%d')
FROM ${TABLE_PREFIX}posts 
WHERE post_status = 'publish' 
AND post_type = 'post'
ORDER BY post_date DESC
" | while IFS=$'\t' read -r url lastmod; do
    cat >> "$OUTPUT_FILE" << EOF
  <url>
    <loc>$DOMAIN$url</loc>
    <lastmod>$lastmod</lastmod>
  </url>
EOF
done

echo "</urlset>" >> "$OUTPUT_FILE"
chown wwwrun:wwwrun "$OUTPUT_FILE"

 

実行時間は以下の通りです。めちゃはやいですね。

 

time ./make-sitemap.sh

real    0m0.258s
user    0m0.149s
sys     0m0.114s

 

以前使っていたnode.js版がこちらですが、ネットワークへのアクセスがある分かなり処理に時間がかかっていることがわかります。

 

$ cat make-sitemap-past.sh 
#!/bin/bash
/usr/local/bin/sitemap-generator -f sitemap.xml https://bokumin.org



$ time ./make-sitemap-past.sh 
(node:458025) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node22 --trace-warnings ...` to show where the warning was created)

real    0m48.391s
user    0m9.989s
sys     0m0.225s

 

WordPress以外の静的ページの扱い

 

私のサイトは元々Apacheで静的ページを公開しているところに、後からWordPressを導入しました。そのため、静的ページがルートディレクトリ直下、WordPressが/blog配下という構成になっています。
WordPress以外でサイトマップに載せたいページは、手動で指定できるようになっています。見せたくないものを除外するより、載せたいものを指定する方が効率が良いと思い、そういうスクリプトの作りになっています。

 

process_url "/"
process_url "/art-works/"
process_url "/gpg-public-key.txt"
process_url "/others/"
process_url "/spam-check/"
process_url "/amedas-dashboard/"
process_url "/blog/"

 

今回はPriorityやその他の属性は入れず、シンプルにURLと最終更新日だけを取得しています。Googleのボットも基本的にこれらの情報しか見ていないため、細かく設定する必要はないと思います。
静的サイトの日付は、スクリプト内のprocess_url関数で取得しています。

 

process_url() {
    local path="$1"
    local full_path="$WEBROOT$path"
    
    if [[ -f "$full_path" ]]; then
        lastmod=$(date -r "$full_path" +%Y-%m-%d)  # ファイルの更新日時
    elif [[ -d "$full_path" ]]; then
        lastmod=$(date -r "$full_path" +%Y-%m-%d)  # ディレクトリの更新日時
    else
        return
    fi
    ...
}

 

出力結果(サイトマップ)

 

出力されたサイトマップを確認していきます。期待通りの出力になっています。

 

 cat /srv/www/htdocs/sitemap.xml 
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
        http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
  <url>
    <loc>https://bokumin.org/</loc>
    <lastmod>2025-10-31</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/art-works/</loc>
    <lastmod>2025-09-11</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/gpg-public-key.txt</loc>
    <lastmod>2024-10-19</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/others/</loc>
    <lastmod>2025-10-30</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/spam-check/</loc>
    <lastmod>2025-10-03</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/amedas-dashboard/</loc>
    <lastmod>2025-10-03</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/blog/</loc>
    <lastmod>2025-10-29</lastmod>
  </url>
  <url>
    <loc>https://bokumin.org/blog/2025/10/28/btrfs%e3%81%a8opensuse%e3%81%a7raid%e3%82%92%e6%a7%8b%e7%af%89%e3%81%99%e3%82%8braid1-raid0-raid10/</loc>
    <lastmod>2025-10-28</lastmod>

 

※実際に作成されたサイトマップは以下のページから確認できます。
https://bokumin.org/sitemap.xml

 

まとめ

 

今回作成したスクリプトは、完全ローカルで動作し、外部ツールを一切必要としません。システムに標準でインストールされているmariadb、grep、sedのみで実行できるのが良いところかなと思います。処理速度も高速で依存関係がゼロであるため、パッケージ管理やアップデートの手間もかかりません。WordPressのデータベースから直接記事情報を取得するため、クローラーを使う方式と比べて正確性も高く、サーバーへの負荷も最小限に抑えられます。
cronで短いスパンで実行しても問題ないほど軽量なので、新規投稿後すぐにサイトマップを更新することができます。
このスクリプトは、ドメイン名やパス、データベース情報などを少し手直しすれば、誰でも使えるようになっています。個人のウェブサイトでサイトマップを作りたいと考えている方の参考になれば幸いです。

 

おわり