XMLSiteMap.py 技術ドキュメント

プログラムの動作

XMLSiteMap.py は、指定されたウェブサイトを再帰的にクロールし、発見されたすべてのHTMLページのURL、タイトル、および最終更新日(可能であれば)を含むXMLサイトマップを自動生成するPythonスクリプトです。このプログラムは、検索エンジンがウェブサイトのコンテンツをより効果的に発見し、インデックスに登録するのに役立つサイトマップを、手動での作成の手間なしに提供することを目的としています。

主な機能は以下の通りです。

  • ウェブサイトのクロール: 指定されたルートURLから開始し、同じドメイン内のリンクを再帰的にたどって、ウェブサイト内のすべてのHTMLページを探索します。

  • メタデータ抽出: 各HTMLページから、ページのタイトル(<title>タグ)を抽出し、またHTTPレスポンスヘッダーの Last-Modified フィールドから最終更新日を取得します。

  • 文字コードの自動検出: 取得したHTMLコンテンツの文字コードを自動で判別し、適切にデコードします。

  • URLの正規化: クロール中に発見されたURLを標準化し、重複を避けます。

  • XMLサイトマップの生成: クロール中に収集したURLとメタデータ(タイトル、最終更新日)を使用して、XML形式のサイトマップを生成します。生成されるサイトマップは、標準的なSitemapプロトコルに加えて、各URLのタイトル情報もカスタム要素として含みます。

  • コマンドライン引数による設定: クロールを開始するルートURLと、出力ファイル名をコマンドライン引数として指定できます。

このプログラムは、ウェブマスターがウェブサイトの構造変更やコンテンツ更新のたびにサイトマップを手動で更新する労力を軽減し、常に最新の情報を反映したサイトマップを提供することで、検索エンジン最適化(SEO)のプロセスを支援します。

原理

XMLSiteMap.py は、ウェブクローリングとXML生成の技術を組み合わせて動作します。

  1. URLの取得と初期設定: プログラムはまず、コマンドライン引数からクロールの開始点となるルートURLと、結果を保存する出力ファイルパスを取得します。urllib.parse モジュールを使用してルートURLからベースドメインを抽出し、クロールの範囲をそのドメイン内に限定します。

  2. 再帰的クロールアルゴリズム (crawl_recursive): 本プログラムの中核は、深さ優先探索 (DFS) に似た再帰的なクロールアルゴリズムです。

    • 訪問済みチェック: visited セットを用いて、すでにクロールしたURLを管理し、無限ループや重複クロールを防ぎます。URLはフラグメント部分を除去して正規化されます。

    • HTTPリクエスト: requests ライブラリを使用して指定されたURLにHTTP GETリクエストを送信し、ページのコンテンツを取得します。HTTPステータスコードが200(OK)でない場合は、そのURLの処理をスキップします。

    • 文字コード検出: charset_normalizer ライブラリを使用して、レスポンスボディのバイナリデータから最適な文字コードを自動的に検出します。これにより、様々なエンコーディングのウェブページに対応できます。

    • メタデータ抽出:

      • 最終更新日: レスポンスヘッダーの Last-Modified フィールドが存在する場合、その値を解析し、YYYY-MM-DD 形式に変換して保存します。

      • ページタイトル: デコードされたHTMLコンテンツから、正規表現 $r"<title>(.*?)</title>"$ を使用してページのタイトルを抽出します。

    • リンク抽出: 正規表現 $r"url:\s*[\"']([^\"']+)[\"']|href=[\"']([^\"']+)[\"']|src=[\"']([^\"']+)[\"']"$ を用いて、HTMLコンテンツ内から href, src, url: 属性を持つリンクをすべて抽出します。

    • URLの解決とフィルタリング:

      • 抽出された相対URLは urllib.parse.urljoin を使用して絶対URLに変換されます。

      • is_target_url 関数により、URLが .html.shtml で終わるか、またはパスの末尾が / (ディレクトリ)である場合にのみクロールの対象とします。

      • urlparse(url).netloc == base_domain の条件で、抽出されたリンクがベースドメインと一致するかをフィルタリングし、外部サイトへのリンクはクロールしません。

    • 再帰呼び出し: フィルタリングされた各内部リンクに対して、crawl_recursive 関数を再帰的に呼び出し、ウェブサイト全体を探索します。

    • 結果の集約: 各クロールラウンドで得られたURLとメタデータ(タイトル、最終更新日)は辞書として集約され、最終的にすべてのクロール結果が返されます。

  3. XMLサイトマップの生成 (generate_xml_sitemap_with_metadata):

    • xml.etree.ElementTree を使用して、標準的なXMLサイトマップの構造を構築します。

    • ルート要素として <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> を作成します。

    • クロールで収集された各URLに対し、<url> 要素を作成し、その子要素として loc (URL), title (ページタイトル), lastmod (最終更新日、存在すれば), changefreq (monthly固定), priority (1.0固定) を追加します。

    • title 要素は標準のSitemapプロトコルには存在しませんが、このプログラムでは検索エンジンやユーザーにとって有用な情報として特別に付加されます。

    • 生成されたXMLツリーは ET.tostring でバイト列に変換され、xml.dom.minidom.parseStringtoprettyxml(indent=" ") を使用して、人間が読みやすいように整形されます。

    • 整形されたXMLは、指定された出力ファイルにUTF-8エンコーディングで書き込まれます。

このプロセスにより、ウェブサイトの構造と各ページの重要なメタデータが網羅された、整理されたXMLサイトマップが生成されます。

必要な非標準ライブラリとインストール方法

XMLSiteMap.py は、以下の非標準ライブラリに依存しています。

  • requests: HTTPリクエストを送信するために使用されます。

  • charset-normalizer: ウェブページコンテンツの文字コードを自動検出するために使用されます。

これらのライブラリは、Pythonのパッケージマネージャーである pip を使用してインストールできます。以下のコマンドをターミナルで実行してください。

pip install requests charset-normalizer

必要な入力ファイル

このプログラムは、実行時に特定の入力ファイルを必要としません。 クロールを開始するルートURLは、コマンドライン引数として直接指定されます。

生成される出力ファイル

プログラムは、指定されたパスにXML形式のサイトマップファイルを生成します。デフォルトのファイル名は sitemap.xml です。

このファイルは、以下のような構造を持ちます。

<?xml version="1.0" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://example.com/page1.html</loc>
    <title>Page 1 Title</title>
    <lastmod>2023-10-26</lastmod>
    <changefreq>monthly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>http://example.com/subdirectory/page2.html</loc>
    <title>Subdirectory Page 2</title>
    <lastmod>2023-10-25</lastmod>
    <changefreq>monthly</changefreq>
    <priority>1.0</priority>
  </url>
  <!-- その他のクロールされたURLが続く -->
</urlset>
  • <urlset>: サイトマップのルート要素で、SitemapプロトコルのXML名前空間を定義します。

  • <url>: サイトマップ内の個々のURLに関する情報を格納する要素です。

  • <loc>: ページのURLを指定します。

  • <title>: クロールされたページのタイトル(<title>タグの内容)を格納します。これは標準のSitemapプロトコルにはないカスタム要素ですが、本プログラムによって追加されます。

  • <lastmod>: ページの最終更新日を YYYY-MM-DD 形式で指定します。これはHTTPレスポンスの Last-Modified ヘッダーから取得されます。

  • <changefreq>: ページの更新頻度を示します。このプログラムでは "monthly" に固定されています。

  • <priority>: サイト内でのページの相対的な優先度を示します。このプログラムでは "1.0" に固定されています。

コマンドラインでの使用例 (Usage)

XMLSiteMap.py は、以下の形式でコマンドラインから実行します。

python XMLSiteMap.py [RootURL] [OutputFile]
  • [RootURL]: クロールを開始するウェブサイトのルートURLです。これは必須引数です。

  • [OutputFile]: 生成されるXMLサイトマップを保存するファイルパスです。この引数は任意です。省略された場合、デフォルトで ./sitemap.xml に保存されます。

コマンドラインでの具体的な使用例

ここでは、http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs を例として使用します。

例1:デフォルトの出力ファイル名で実行

クロールを開始するURLのみを指定し、出力ファイル名をデフォルト (sitemap.xml) のままにする場合。

python XMLSiteMap.py http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs

実行結果の説明:

実行すると、以下のような情報が標準出力に表示されます。

Crawling and generating XML Sitemap with metadata...

usage: python XMLSiteMap.py [RootURL] [OutputFile]

RootURL: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs
Output File: sitemap.xml
Base Domain: d2mate.mdxes.iir.isct.ac.jp

Starting crawl from: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs
Crawling: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs
 Encoding: UTF-8
 lastmod: 2024-03-27
 title: D2MatE -- Database of Data-driven Materials Science Projects
Crawling: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_top.html
 Encoding: UTF-8
 lastmod: 2024-03-27
 title: D2MatE -- Database of Data-driven Materials Science Projects
Crawling: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=list
 Encoding: UTF-8
 lastmod: 2024-03-27
 title: D2MatE -- Database of Data-driven Materials Science Projects
... (同様のクロールログが続く) ...
Found total URLs: N
 [1] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_contact.html - Title: D2MatE -- Database of Data-driven Materials Science Projects - LastMod: 2024-03-27
 [2] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=faq - Title: D2MatE -- Database of Data-driven Materials Science Projects - LastMod: 2024-03-27
... (クロールされたURLのサマリーが続く) ...
XML Sitemap with metadata has been saved as 'sitemap.xml'

この実行により、sitemap.xml というファイルが現在のディレクトリに生成され、クロールされたすべてのページのURL、タイトル、最終更新日を含むXMLサイトマップが保存されます。

例2:出力ファイル名を指定して実行

クロールを開始するURLと、カスタムの出力ファイル名(例:my_website_sitemap.xml)を指定する場合。

python XMLSiteMap.py http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs my_website_sitemap.xml

実行結果の説明:

実行時の出力は例1とほぼ同じですが、Output File の表示と最後の保存メッセージが指定したファイル名に変わります。

Crawling and generating XML Sitemap with metadata...

usage: python XMLSiteMap.py [RootURL] [OutputFile]

RootURL: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs
Output File: my_website_sitemap.xml
Base Domain: d2mate.mdxes.iir.isct.ac.jp

Starting crawl from: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs
... (クロールログが続く) ...
Found total URLs: N
... (クロールされたURLのサマリーが続く) ...
XML Sitemap with metadata has been saved as 'my_website_sitemap.xml'

この実行により、my_website_sitemap.xml というファイルが現在のディレクトリに生成され、クロールされたすべてのページのURL、タイトル、最終更新日を含むXMLサイトマップが保存されます。