Webマスターツールでエラーが出ていたので調べると,どうもGoogleがサイトマップファイル(sitemap.txt)に要求しているURLのパーセントエンコーディングは,記号類の扱いでカモランドの想定とは違っているようだ.

GoogleサイトマップのURLエンコーディング

Google Webマスターツールで,また新たなエラーが出ていた.
HTTP エラー:301 (恒久的に移動)
URL:http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD(4)
エラー検出日:2009/03/03
Googleの説明によると,こういうことらしい.
サイトマップの URL のサンプルをテストしたところ,一部の URL が別のページ
にリダイレクトされることがわかりました.サイトマップには,他の URL にリダ
イレクトされる URL ではなく,最終的なリンク先 (リダイレクト先) の URL を
指定するようお勧めします.
このエラーの場合,正式なURLは
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD%284%29
なので,サイトマップ(sitemap.txt)に載せているURLは
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD%284%29
にしてあるのに,GoogleBotが
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD(4)
をGETするので,カモランド側で正式なURL
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD%284%29
に301リダイレクトしている状況.つまり,現象としては
  • サイトマップのURLとリダイレクト先のURLは一致するので正しいはずだが,GoogleBotがサイトマップとは違ったURLでアクセスしてくるため,結果として余計なリダイレクトが発生している

googlebot1.png

このリダイレクトを,Webマスターツールでは問題視している. サイトマップファイルの不備だと怒られている.

GoogleBotがなぜ違ったURLでアクセスするのか?

GoogleBotは,パーセントエンコーディングを一部デコードしたURLに,アクセスしてきている. この現象だけを見ると,このようにデコードされた文字については,元々エンコードせずにサイトマップに載せれば良いということになる. 具体的には,サイトマップのURLを,以下のように「(」「)」を含むものにすればよいはず.
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD(4)
しかし,この文字だけでよいのか,そもそもどういう規則なのかがわからない.

仕方がないので,RFC-3986をまじめに読むことにした.

以前読んだときの解釈

以前は,RFC3986を斜め読みしてそれっぽい箇所
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
を見つけ,ここに含まれる文字以外をパーセントエンコーディングすれば良いものだと思っていた. しかしよく読むと,違った解釈の余地もありそうだ.

まじめに読み直す

今回問題となっている箇所は,URLの構成
     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
のうちの「query」の箇所だ.これは,
3.4.  Query
query       = *( pchar / "/" / "?" )
とのこと.内訳は,
pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
            / "*" / "+" / "," / ";" / "="
となっているので, queryには従来カモランドで許可としていたunreserved群以外にも,以下の文字が使えるらしい.
sub-delims群 !$&'()*+,;=
pchar追加分  :@
query追加分  /?
つまり「(」「)」がURLのクエリー部に含まれるのは,間違いではないようだ.(= GoogleBotはおかしくはない)

しかし逆に「(」「)」を「%28」「%29」にパーセントエンコーディングした場合(カモランド方式)でも, 間違いというわけではないはずだが, GoogleBotが方針としてURLのパーセントエンコーディングを最小限に抑えるということだと推測すれば, まぁ辻褄があう.

URLエンコーディング方法の変更案

このGoogleBotの挙動を踏まえると,こういう実装案になる.
以下の文字は生のまま残して,それ以外の文字をパーセントエンコーディングする
a-zA-Z0-9-._~!$'()*+,;:@/?
「&」「=」を除外しているのは,これは生のまま残すとWikiがパラメータの区切り文字として解釈するので, 誤動作してしまうためである. RFC的には許されるが,アプリの入力仕様としては許されないという話.

サイトマップ対応のURLエンコーディング実装案

・perl
s/([^a-zA-Z0-9\-\._~!\$'\(\)\*+,;:\@\/\?])/'%'.uc(unpack('H2', $1))/eg;

・ruby
str.gsub(/([^a-zA-Z0-9\-\._~!\$'\(\)\*+,;:\@\/\?])/) { "%#{$1.unpack('H*')[0].scan(/../).join('%').upcase }" }
...このエンコーディング法を使って生成したURLをサイトマップに載せれば, おそらく問題は解決するのだと思われる.

しっかし正式なURLを移転するというのは,ソーシャルブックマーク対策の関係で気がすすまぬ. しかもGoogleのためだけにとは ヽ(`Д´)ノ

結局,URLのエンコーディング法はそのままで,Googleサイトマップを使うのをやめた ヽ(`Д´)ノ ヽ(`Д´)ノ


© 2024 KMIソフトウェア