XMLSiteMap.py 技術ドキュメント

プログラムの動作

XMLSiteMap.py は、指定されたウェブサイトをクロールし、その構造とメタデータに基づいてXMLサイトマップを自動生成するPythonスクリプトです。このプログラムは、検索エンジン最適化(SEO)の目的で、ウェブサイトの全てのページを検索エンジンに効率的に通知するためのSitemapプロトコルに準拠したファイルを作成します。

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

  • ウェブクローリング: 指定されたルートURLから開始し、同じドメイン内のリンクを再帰的にたどってウェブページを探索します。.html.shtmlファイル、またはディレクトリパスのみをクロール対象とします。

  • メタデータ抽出:

    • 各ページのHTMLコンテンツから<title>タグの内容を抽出し、ページのタイトルとして記録します。

    • HTTPレスポンスヘッダーのLast-Modifiedフィールドから、ページの最終更新日時を取得し、YYYY-MM-DD形式でフォーマットします。

  • URLの正規化とフィルタリング:

    • URLのフラグメント(#以降の部分)を削除し、同じコンテンツを指す重複URLを避けます。

    • クロール対象をスクリプト実行時に指定されたルートURLと同じドメインに限定します。

    • 画像、CSS、JavaScriptなどの非HTMLリソースへのリンクは無視します。

  • 文字エンコーディングの自動検出: charset_normalizerライブラリを使用して、HTTPレスポンスのバイトコンテンツから最適な文字エンコーディングを自動で判別し、コンテンツを正確にデコードします。

  • XMLサイトマップ生成: 収集したURL、タイトル、最終更新日時などのメタデータを用いて、Sitemapプロトコル(バージョン0.9)に準拠したXMLファイルを生成します。生成されるXMLは整形(pretty-print)されて出力されます。

このプログラムは、ウェブサイトのページを手動で登録する手間を省き、サイトの更新状況を検索エンジンに効果的に伝えることで、ウェブサイトのインデックス作成と可視性の向上に貢献します。

原理

XMLSiteMap.py は、ウェブサイトの構造を探索し、必要な情報を抽出するためにいくつかの標準的なウェブ技術とアルゴリズムを利用しています。

クローリングアルゴリズム

本プログラムのウェブクローラーは、実質的に深さ優先探索(DFS: Depth-First Search)アプローチを採用しています。

  1. 開始点: コマンドライン引数またはデフォルトで指定されたルートURLからクロールを開始します。

  2. 訪問済み管理: visitedというセットを用いて、既にクロールした正規化されたURLを記録します。これにより、無限ループや重複したページのクロールを防ぎます。

  3. HTTPリクエスト: requestsライブラリを用いて指定されたURLにHTTP GETリクエストを送信し、ページのコンテンツとHTTPヘッダーを取得します。

  4. 文字エンコーディング検出: 取得したHTTPレスポンスのバイトコンテンツに対し、charset_normalizer.detect() 関数を使用して最も適切な文字エンコーディングを推定します。これにより、多様なウェブページの文字化けを防ぎます。

  5. HTML解析と情報抽出:

    • タイトル: 正規表現 r"<title>(.*?)</title>" を用いてHTMLコンテンツから<title>タグの内容を抽出します。

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

  6. URLの正規化とフィルタリング:

    • 抽出された各URLは urllib.parse.urlparseurllib.parse.urlunparse を使用してフラグメント(#以降の部分)が削除され、標準化されます。

    • urllib.parse.urljoin を使用して相対URLを絶対URLに変換します。

    • URLのドメインが初期のbase_domainと一致するか確認し、外部ドメインへのリンクはクロール対象から除外します。

    • .html.shtmlで終わるパス、またはスラッシュ(/)で終わるパス(ディレクトリを示す)のみを有効なクロール対象とします。

  7. 再帰的クロール: フィルタリングされた有効な各リンクに対して、再度このクロール関数を再帰的に呼び出し、サイト全体を探索します。

XMLサイトマップの生成原理

収集されたURLとそのメタデータ(タイトル、最終更新日時)は、以下のSitemapプロトコルに準拠したXML構造に変換されます。

  • ルート要素: <urlset>はサイトマップ全体のルート要素であり、SitemapプロトコルのXML名前空間 xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" を指定します。

  • URLエントリ: 各ウェブページは <url> 要素で表現されます。

  • ページロケーション: <loc> 要素は、ページの完全なURLを含みます。

  • ページタイトル: <title> 要素は、抽出されたページのタイトルを含みます。これはSitemapプロトコル標準にはない拡張要素ですが、このプログラムで追加されます。

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

  • 更新頻度: <changefreq> 要素は、ページの変更頻度を示し、本プログラムでは固定で monthly に設定されます。

  • 優先度: <priority> 要素は、同じサイト内の他のURLに対するページの相対的な優先度を示し、本プログラムでは固定で 1.0 に設定されます。

これらの要素は xml.etree.ElementTree ライブラリを使用して構築され、最終的に xml.dom.minidom.parseString を用いて整形されたXML文字列としてファイルに書き出されます。

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

このプログラムの実行には、以下の非標準ライブラリが必要です。

  • requests: HTTPリクエストを送信してウェブページを取得するために使用されます。

  • charset_normalizer: HTTPレスポンスのバイトコンテンツから文字エンコーディングを自動的に検出するために使用されます。

これらのライブラリは pip コマンドを使用してインストールできます。

pip install requests charset_normalizer

必要な入力ファイル

XMLSiteMap.py は、外部の入力ファイルを直接必要としません。プログラムは、コマンドライン引数として与えられたルートURLからウェブサイトのコンテンツを直接取得します。

もしコマンドライン引数が指定されない場合、プログラムはデフォルトのルートURL http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs を使用します。

生成される出力ファイル

プログラムは、クロールして収集した情報に基づいてXML形式のサイトマップファイルを生成します。

  • ファイル名:

    • デフォルトでは sitemap.xml です。

    • コマンドライン引数によって任意のファイルパスを指定することができます。

  • 内容:

    • Sitemapプロトコル(バージョン0.9)に準拠したXMLドキュメントです。

    • XMLの名前空間は http://www.sitemaps.org/schemas/sitemap/0.9 となります。

    • ファイルは <urlset> ルート要素を持ち、その中に発見された各ウェブページに対応する複数の <url> 要素を含みます。

    • <url> 要素は以下のサブ要素を持ちます:

      • <loc>: ページの絶対URL。

      • <title>: ページのHTML <title> タグから抽出されたタイトル。

      • <lastmod>: ページの最終更新日時。HTTPレスポンスのLast-Modifiedヘッダーから取得され、YYYY-MM-DD形式で表現されます。情報がない場合はこの要素は省略されます。

      • <changefreq>: ページの更新頻度。このプログラムでは常に monthly となります。

      • <priority>: サイト内の他のURLに対する相対的な優先度。このプログラムでは常に 1.0 となります。

出力XMLファイルの例:

<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://example.com/</loc>
    <title>Example Domain</title>
    <lastmod>2023-10-26</lastmod>
    <changefreq>monthly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>http://example.com/page1.html</loc>
    <title>Page One</title>
    <lastmod>2023-10-25</lastmod>
    <changefreq>monthly</changefreq>
    <priority>1.0</priority>
  </url>
</urlset>

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

XMLSiteMap.py は、コマンドライン引数を使用してクロール開始URLと出力ファイルパスを指定できます。

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

    • クロールを開始するウェブサイトのURLを指定します。

    • この引数を省略した場合、プログラムはデフォルトで組み込まれているURL (http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs) を使用します。

  • [OutputFile]:

    • 生成されるXMLサイトマップを保存するファイルパスを指定します。

    • この引数を省略した場合、出力ファイルはデフォルトで sitemap.xml となります。

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

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

プログラムに引数を与えずに実行すると、コードに組み込まれたデフォルトのルートURLをクロールし、結果を sitemap.xml に保存します。

python XMLSiteMap.py

実行結果の画面出力(抜粋):

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: 2023-10-26
 title: D2MatE programs (statistics)
Crawling: http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/
 Encoding: UTF-8
 lastmod: 2023-10-26
 title: D2MatE TOP page
... (以下、クロールされたURLごとに同様の出力が続く)

Found total URLs: 5
 [1] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/ - Title: D2MatE TOP page - LastMod: 2023-10-26
 [2] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_intro.html - Title: Introduction of D2MatE - LastMod: 2023-10-26
 [3] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_members.html - Title: D2MatE members - LastMod: 2023-10-26
 [4] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_programs.html?page=statistcs - Title: D2MatE programs (statistics) - LastMod: 2023-10-26
 [5] http://d2mate.mdxes.iir.isct.ac.jp/D2MatE/D2MatE_results.html - Title: D2MatE results - LastMod: 2023-10-26
XML Sitemap with metadata has been saved as 'sitemap.xml'

この実行により、sitemap.xml というファイルが生成され、クロールされたURLとそのメタデータがXML形式で格納されます。

例2: 特定のURLを指定し、カスタムファイル名で出力

http://example.com/ をクロールし、結果を my_website_sitemap.xml というファイルに保存する例です。

python XMLSiteMap.py http://example.com/ my_website_sitemap.xml

実行結果の画面出力(抜粋):

Crawling and generating XML Sitemap with metadata...

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

RootURL: http://example.com/
Output File: my_website_sitemap.xml
Base Domain: example.com

Starting crawl from: http://example.com/
Crawling: http://example.com/
 Encoding: UTF-8
 lastmod: 2023-10-26
 title: Example Domain
Crawling: http://example.com/page1.html
 Encoding: UTF-8
 lastmod: 2023-10-25
 title: Page One
...

Found total URLs: 2
 [1] http://example.com/ - Title: Example Domain - LastMod: 2023-10-26
 [2] http://example.com/page1.html - Title: Page One - LastMod: 2023-10-25
XML Sitemap with metadata has been saved as 'my_website_sitemap.xml'

この実行により、my_website_sitemap.xml というファイルが生成され、指定されたURLとその配下のページ情報がXML形式で記述されます。