
突然ですが…

サイトマップを設置しましたー!!
はてなブログでHTML形式のサイトマップを作りたかったのですが、手動で作る方法しか知らなくて断念していました。
500記事を超えたので、もはや一つずつ作る気力はなく…
もうなくてもいいかな…と。
でもPythonのコードも書いてくれるという、ChatGPT (無料) にお願いしたらできるのではないか…?あわよくば自動化とかできるんじゃ…?
と。
ということでお願いしてみました。
ChatGPTと一緒にHTMLサイトマップを作ろう(作ってもらおう)

わあ!作ってくれるって!!(≧▽≦)
いろいろ提案してもらったのですが、JavaScriptを使って自動生成してくれる、このパターンでお願いしてみることにしました。
RSSフィードからの取得なので、多くて新着100件(さっき見てみたら30件くらいしか表示されていなかったけど)、昔の記事は表示されないというのが少し惜しいけど(RSSフィードの何かを変えたらいけるかもしれないとか言われましたが、よく分からないし…)でも多分これは私が求めていたことに最も近い。
とりあえずざっくりお願いして、作ってもらったコードで表示してみながらイメージに近づけていくことにしました。
繰り返すこと数回…(フリーユーザーなのに、なんかすみません)。
最終的にこんな感じになりました。



素人の私が自分でやろうと思ったらなかなか大変なことを一瞬で…!!
全コードを作ってくれるので、私はそれをコピペして貼り付けるだけ。

例えばこんな感じになりました。
今みていて、少しだけ見た目を変えてみたくなったので、HTMLを書き換えます。

あ、なんかすっきりした。
HTMLで掻き出してもらったので、微細な修正なら自分でできるのもありがたい。
最後に御礼を言うと、丁寧なお返事が。Chat GPT すごいな。

今回の記事を公開してよいか聞いてみました。

すると…ご快諾頂けたので、参考までにコードを載せさせていただきますね。
今回ChatGPTに作ってもらったコード
先ほど提示していたページのコードです。(2025/6/3現在)
いろいろ好みの指示を入れているので、このまま使うより、新たにChatGPTと相談しながら作ることをおすすめします✨
<div id="sitemap" style="font-family: sans-serif; padding: 20px; background-color: #fff; color: #000;">
<h2 style="color: #000;">📚 カテゴリー別サイトマップ</h2>
<p style="color: #444;">自由コメント</p>
<div id="categories"></div>
</div>
<p>
<script>
const feedUrl = "https://自分のサイトのURL/rss";
fetch(feedUrl)
.then(response => response.text())
.then(str => new window.DOMParser().parseFromString(str, "text/xml"))
.then(data => {
const items = data.querySelectorAll("item");
const categories = {};
items.forEach(item => {
const title = item.querySelector("title").textContent;
const link = item.querySelector("link").textContent;
const category = item.querySelector("category") ? item.querySelector("category").textContent : "未分類";
const pubDate = new Date(item.querySelector("pubDate").textContent);
if (!categories[category]) {
categories[category] = ;
}
categories[category].push({ title, link, pubDate });
});
const categoriesContainer = document.getElementById("categories");
function getRandomItems(arr, count) {
const _arr = [...arr];
const result = ;
for(let i = 0; i < count && _arr.length > 0; i++) {
const idx = Math.floor(Math.random() * _arr.length);
result.push(_arr.splice(idx, 1)[0]);
}
return result;
}
// 記事数が多い順にカテゴリをソート
const sortedCategories = Object.entries(categories)
.filter*1;
articles.forEach(article => {
if (recommendedTitles.has(article.title)) return; // おすすめ記事と重複回避
const li = document.createElement("li");
li.style.marginBottom = "6px";
const a = document.createElement("a");
a.href = article.link;
a.target = "_blank";
a.textContent = article.title;
a.style.color = "#000";
a.style.textDecoration = "underline";
const date = document.createElement("span");
date.textContent = `(${article.pubDate.toLocaleDateString()})`;
date.style.color = "#666";
date.style.fontSize = "0.9em";
date.style.marginLeft = "6px";
li.appendChild(a);
li.appendChild(date);
list.appendChild(li);
});
toggle.addEventListener("click", () => {
const isVisible = list.style.display === "block";
list.style.display = isVisible ? "none" : "block";
toggle.textContent = isVisible ? "▶ 他の記事を表示" : "▼ 閉じる";
});
section.appendChild(list);
categoriesContainer.appendChild(section);
}
})
.catch(error => {
console.error("サイトマップ取得中にエラーが発生しました:", error);
document.getElementById("sitemap").innerHTML = "サイトマップの読み込みに失敗しました。";
});
</script>
</p>
それではこのへんで!(*'▽')/
※この下に多分コードが追加されています。上の枠内にコードをコピペして貼っただけなのですが、多分はてなブログの仕様で一部外に出されてしまいました。。

この部分は、本当はこうなっています(↓)。
直し方が分からないので、今回はこのまま掲載させて頂きます…(´;ω;`)

以下、押し出された部分------------------------------------
*1:[_, articles]) => articles.length > 0)
.sort((a, b) => b[1].length - a[1].length);
for (const [category, articles] of sortedCategories) {
const section = document.createElement("section");
section.style.marginBottom = "30px";
// カテゴリリンク付き見出し
const heading = document.createElement("h3");
const categoryLink = document.createElement("a");
const encodedCategory = encodeURIComponent(category);
categoryLink.href = `https://自分のサイトのURL/archive/category/${encodedCategory}`;
categoryLink.textContent = category;
categoryLink.style.color = "#000";
categoryLink.style.textDecoration = "none"; // 下線なし
categoryLink.style.transition = "color 0.3s";
categoryLink.style.cursor = "pointer";
categoryLink.addEventListener("mouseenter", () => categoryLink.style.color = "#555");
categoryLink.addEventListener("mouseleave", () => categoryLink.style.color = "#000");
categoryLink.target = "_blank";
heading.appendChild(categoryLink);
section.appendChild(heading);
// おすすめ記事3件(ランダム)
const featuredArticles = getRandomItems(articles, 3);
featuredArticles.forEach(article => {
const featuredEl = document.createElement("p");
featuredEl.innerHTML = `<strong>☆</strong> <a href="${article.link}" target="_blank" style="color: #000; text-decoration: underline;">${article.title}</a> <span style="color:#666; font-size:0.9em;">(${article.pubDate.toLocaleDateString()})</span>`;
featuredEl.style.marginBottom = "6px";
section.appendChild(featuredEl);
});
// アコーディオン開閉ボタン(背景なし、枠なし)
const toggle = document.createElement("button");
toggle.textContent = "▶ 他の記事を表示";
toggle.style.cursor = "pointer";
toggle.style.marginBottom = "8px";
toggle.style.background = "transparent";
toggle.style.border = "none";
toggle.style.padding = "5px 10px";
toggle.style.fontSize = "0.9em";
toggle.style.borderRadius = "4px";
toggle.style.color = "#000";
toggle.style.transition = "color 0.3s";
toggle.addEventListener("mouseenter", () => toggle.style.color = "#555");
toggle.addEventListener("mouseleave", () => toggle.style.color = "#000");
section.appendChild(toggle);
// 記事リスト
const list = document.createElement("ul");
list.style.display = "none";
list.style.paddingLeft = "20px";
// おすすめ3件は除外して表示
const recommendedTitles = new Set(featuredArticles.map(a => a.title



