サイトマップって、作るのは自動が良いですよね。
で、作るのも面倒なんで、Geminiと相談してこんなん作成しました。
引数に、作りたい URL をセットすることで、適当なサイトマップが出力されます。
指定URLに対して、前方一致するものだけを対象にしますよ。
#!/usr/bin/python3
import sys
import requests
from bs4 import BeautifulSoup
import xml.etree.ElementTree as ET
import argparse
def is_internal_link(url, site_base_url_prefix):
"""
URL が指定されたプレフィックスで始まるか判定する(非推奨な場合あり)。
Args:
url (str): 判定したい絶対URL文字列(urljoinで変換済みを想定)。
site_base_url_prefix (str): 自サイトの正確な開始プレフィックス(例: 'https://www.your-site.com/')。
Returns:
bool: 内部リンクとみなせれば True、そうでなければ False。
"""
# urljoin で絶対URLに変換された後の url を想定
if url.startswith(site_base_url_prefix):
# ただし、フラグメント (#...) や mailto:, tel: などは別途除外が必要
if '#' in url or url.startswith('mailto:') or url.startswith('tel:'):
return False
return True
else:
return False
def recursive_crawl_site(site_domain, url, visited):
if url in visited:
return [] # すでに訪れたURLなら処理しない
visited.add(url)
all_urls = [url] # このURL自体も収集
try:
response = requests.get(url)
response.raise_for_status()
soup = BeautifulSoup(response.content, 'html.parser')
for link in soup.find_all('a', href=True):
href = link['href']
next_url = requests.compat.urljoin(url, href)
# ここで自サイト内リンクか判定し、必要なら正規化・フィルタリング
# is_internal_link 関数を仮定
if is_internal_link(next_url, site_domain) and next_url not in visited:
# 再帰呼び出し
all_urls.extend(recursive_crawl_site(site_domain, next_url, visited))
except requests.exceptions.RequestException as e:
print(f"Error crawling {url}: {e}", file=sys.stderr)
# エラー時も再帰は停止しない(設計による)
return all_urls
def generate_sitemap_xml(urls):
urlset = ET.Element('urlset', xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
for url in urls:
url_element = ET.SubElement(urlset, 'url')
loc = ET.SubElement(url_element, 'loc')
loc.text = url
# 必要に応じて <lastmod>, <changefreq>, <priority> を追加
# XML宣言を追加して整形
tree = ET.ElementTree(urlset)
ET.indent(tree, space=" ") # 整形
return ET.tostring(urlset, encoding='utf-8', xml_declaration=True)
# オプション処理
TARGETURL = "https://hogehoge.domain.com/"
DEBUG = False
parser = argparse.ArgumentParser(description='using \n \nex)\n mksitemap.py "https://hogehoge.domain.com"')
parser.add_argument('url', help='url')
if DEBUG == False :
args = parser.parse_args()
TARGETURL=args.url
# 実行例
if __name__ == "__main__":
site_url = TARGETURL
visited = set()
discovered_urls = recursive_crawl_site(site_url,site_url,visited)
sitemap_xml_bytes = generate_sitemap_xml(discovered_urls)
sitemap_xml_string = sitemap_xml_bytes.decode('utf-8')
print(sitemap_xml_string)