<?xml version="1.0" encoding="utf-8" ?>

<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:georss="http://www.georss.org/georss"
>

<channel rdf:about="http://kamoland.com">
 <title>KamoLand</title>
 <link>http://kamoland.com</link>
 <description>自宅サーバの構築と運用</description>
 <items>
  <rdf:Seq>
   <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?Disqus%A4%F2%BD%FC%B5%EE%A4%B7%A4%BF%A5%B5%A5%A4%A5%C8%A4%CE%A5%D1%A5%D5%A5%A9%A1%BC%A5%DE%A5%F3%A5%B9" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?%A5%DA%A1%BC%A5%B8%A4%CE%BD%A4%C0%B5%A4%F2RSS%A4%C7%C9%BD%B8%BD%A4%B9%A4%EB" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%282%29" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%283%29" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?BASIC%C7%A7%BE%DA%A4%CE%A5%D1%A5%B9%A5%EF%A1%BC%A5%C9%A4%CF8%CA%B8%BB%FA%A4%AB" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?Google%A5%B5%A5%A4%A5%C8%A5%DE%A5%C3%A5%D7%A4%CEURL%A5%A8%A5%F3%A5%B3%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?GoogleBot%A4%CB302%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8%A4%CF%B6%D8%CA%AA" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?%B0%D9%C2%D8%A5%EC%A1%BC%A5%C8%A4%CERSS%A4%F2%C0%B8%C0%AE%A4%B9%A4%EB" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?RSS%A4%C7%C1%B4%CA%B8%C7%DB%BF%AE%A4%B9%A4%EB" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?RSS%A4%CB%A4%C4%A4%A4%A4%C6" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?META%A5%BF%A5%B0%A4%CF%CC%B5%B0%D5%CC%A3%A4%C7%A4%CF%A4%CA%A4%A4%A4%E8%A4%A6%A4%C0" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%B2%F2%C0%CF%A4%F2DB%A4%C7%A4%E4%A4%EB" /> <rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%A4%F2DB%A4%C7%B2%F2%C0%CF%A4%B9%A4%EB" />
  </rdf:Seq>
 </items>
</channel>

   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?Disqus%A4%F2%BD%FC%B5%EE%A4%B7%A4%BF%A5%B5%A5%A4%A5%C8%A4%CE%A5%D1%A5%D5%A5%A9%A1%BC%A5%DE%A5%F3%A5%B9">
    <title>Disqusを除去したサイトのパフォーマンス</title>
    <link>http://kamoland.com/wiki/wiki.cgi?Disqus%A4%F2%BD%FC%B5%EE%A4%B7%A4%BF%A5%B5%A5%A4%A5%C8%A4%CE%A5%D1%A5%D5%A5%A9%A1%BC%A5%DE%A5%F3%A5%B9</link>
    <description>カモランドからDisqusコメントシステムを除去すると，Googleウェブマスターツールでのパフォーマンス評価がずいぶん良くなりました．</description>
    <content:encoded><![CDATA[<p>
カモランドからDisqusコメントシステムを除去すると，Googleウェブマスターツールでのパフォーマンス評価がずいぶん良くなりました．

</p>
<h2><a name="i0"> </a>Disqusを除去したサイトのパフォーマンス</h2>
以前，カモランドに<a title="WikiにDisqusを組み込む" href="http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0">Disqusコメントシステムを導入しました</a>．
<p>
しかしJavaScriptが重いし，裏でGoogle Analyticsを呼び出して何か統計を取っているので，嫌気が差してしまいました．
</p>
<p>
．．．それで結局，除去しました．
</p>
<p>
ちなみに，GoogleウェブマスターツールのLabsで「サイトのパフォーマンス」を見れますが，
こんな感じになりました．
</p>
<p>
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=speed.png&amp;mypage=Disqus%A4%F2%BD%FC%B5%EE%A4%B7%A4%BF%A5%B5%A5%A4%A5%C8%A4%CE%A5%D1%A5%D5%A5%A9%A1%BC%A5%DE%A5%F3%A5%B9&amp;refer=Disqus%A4%F2%BD%FC%B5%EE%A4%B7%A4%BF%A5%B5%A5%A4%A5%C8%A4%CE%A5%D1%A5%D5%A5%A9%A1%BC%A5%DE%A5%F3%A5%B9" title="speed.png"><img src="http://kamoland.com/wiki/attach/446973717573A4F2BDFCB5EEA4B7A4BFA5B5A5A4A5C8A4CEA5D1A5D5A5A9A1BCA5DEA5F3A5B9_73706565642E706E67" alt="speed.png" title="speed.png" width="675" height="164" /></a>
</p>
<p>
Disqusを外してからは，ずいぶん高速だという結果になっています．
</p>]]></content:encoded>
    <dc:date>2010-03-14T00:03:38+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?%A5%DA%A1%BC%A5%B8%A4%CE%BD%A4%C0%B5%A4%F2RSS%A4%C7%C9%BD%B8%BD%A4%B9%A4%EB">
    <title>ページの修正をRSSで表現する</title>
    <link>http://kamoland.com/wiki/wiki.cgi?%A5%DA%A1%BC%A5%B8%A4%CE%BD%A4%C0%B5%A4%F2RSS%A4%C7%C9%BD%B8%BD%A4%B9%A4%EB</link>
    <description>ページを「追加」したのではなく既存のページを「修正」したということは，RSSでうまく表現できない．それを何とかしようと，RSSに更新情報を埋め込むことを考えた</description>
    <content:encoded><![CDATA[<p>
ページを「追加」したのではなく既存のページを「修正」したということは，RSSでうまく表現できない．それを何とかしようと，RSSに更新情報を埋め込むことを考えた

</p>

<h2><a name="i0"> </a>ページの修正をRSSで表現する</h2>
最近<a title="Twitterはじめました" href="http://kamoland.com/wiki/wiki.cgi?Twitter%A4%CF%A4%B8%A4%E1%A4%DE%A4%B7%A4%BF">twitterをはじめて</a>思ったが，twitterは単につぶやきを書くという用途の他に，
サイト本体(カモランド)の更新情報を配信するという用途も考えられる．
<p>
サイトの更新情報は既にRSSで配信しているのに，一体なぜそんなことを考えたのか？を自問すると，
RSSによる配信には
</p>
<ul>
<li>新規に追加したページではなく，修正したページの通知がやりにくい</li>
</ul>
<p>
という欠点があるからだと気づいた．
</p>
<p>
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=rss_modpage.jpg&amp;mypage=%A5%DA%A1%BC%A5%B8%A4%CE%BD%A4%C0%B5%A4%F2RSS%A4%C7%C9%BD%B8%BD%A4%B9%A4%EB&amp;refer=%A5%DA%A1%BC%A5%B8%A4%CE%BD%A4%C0%B5%A4%F2RSS%A4%C7%C9%BD%B8%BD%A4%B9%A4%EB" title="rss_modpage.jpg"><img src="http://kamoland.com/wiki/attach/A5DAA1BCA5B8A4CEBDA4C0B5A4F2525353A4C7C9BDB8BDA4B9A4EB_7273735F6D6F64706167652E6A7067" alt="rss_modpage.jpg" title="rss_modpage.jpg" width="330" height="196" /></a>
</p>
<p>
カモランドに新しいページを追加した場合は，
「何月何日に，こういうタイトル，概要のページが追加された」ということをそのままRSSで表現できて，
何の不満もないのだが，以前作成して既に存在しているページを，間違いや最新情報で修正した場合には，
「何月何日に修正したか」は表現できるものの，「どういう内容の修正をしたのか」をRSSでは表現できない．
RSSを見ても，わからない．
</p>
<p>
でまぁ対策として，初めに思ったようにRSSではなくtwitterを使ってみるというのも一案なのだが，twitterでその場限りの投稿をするより，
そのページに紐づくデータとして残しておいた方が後々良いと思うので，現状のカモランド本体のRSS配信の仕組みで何とかすることにした．
</p>
<div></div><h3><a name="i1"> </a>対策案</h3>
<div></div><h4><a name="i2"> </a>(A) 「更新情報そのもののRSS」を配信する</h4>
更新したページのRSSとは別に，更新内容を中身とするRSSを作るという案．
<p>
この場合，更新内容のRSSは更新したページに関連付いていなきゃならんので，
結局，更新内容のRSSも更新したページのRSSも，どちらも同じリソース(= 更新したページのURL)を参照することになる．
</p>
<p>
これは，なんかよくわけがわからん状態なので却下．この文章を書いていてもわけわからん．
</p>
<div></div><h4><a name="i3"> </a>(B) 更新したページのRSSに，更新内容の情報を挿入する</h4>
更新したページのRSSには，上述のようにどういう修正をしたのかの情報がないので不便なわけだが，
それならその情報を載せるようにすればいいのだ．ハッハッハ
<p>
ということで，(B)案で実装することにした．
</p>
<div></div><h3><a name="i4"> </a>実装</h3>
調べてみたが，RSSには「どういう修正をしたか」を記述するための語彙は無いようだ．そこで仕方ないので，
属性の消去法でdescription属性に埋め込むことにした．こんな感じ．
<div>
<pre>
&lt;title&gt;キーワード抽出による関連ページ導出(2)&lt;/title&gt;
&lt;link&gt;http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%282%29&lt;/link&gt;
&lt;description&gt;Webページから単語抽出して遊ぼう．前回は，キーワードとしてふさわしくないような単語まで抽出されて，頭を抱えたところで終わった．【更新】対象の検索エンジンにBingを追加しました (2009-08-01)&lt;/description&gt;
&lt;content:encoded&gt;&lt;![CDATA[&lt;p&gt;
</pre>
</div>
descriptionに書かれていれば，さすがにどんなRSSリーダーでも認識できるだろう．
<p>
そしてWiki本体では，更新履歴を記述するためのWikiのプラグインを作成した．
RSS生成プログラムも改造して，プラグインで記述した更新履歴をdescriptionに付与するようにした．
ページを修正した場合は，このプラグインを使って更新履歴を書くようにすればよい．
</p>
<p>
これで，完成．
</p>
<div></div><h3><a name="i5"> </a>RSSとtwitterの関係 (余談)</h3>
RSSは普及した標準規格であること，twitterはユーザ数が多いこと，という特徴から，
どちらも広範囲に情報を伝達する能力があるので，RSSの代わりにtwitterを使うという考え方もあり得ると思う．
(最初の話ですが)
<p>
例えばこの記事では，そういう伝達能力だけでなく，twitterのソーシャルな点にも着目している．
</p>
<ul>
<li><a href="http://blogs.itmedia.co.jp/speedfeed/2009/05/twitterrss-a9f6.html">TwitterがRSSを蹴落としてフィードの主役になる？</a></li>
</ul>
<p>
ソーシャルだからどうこうという話は，俺にはよくわからないが，twitterの用途として興味深いのは確か．
</p>
<p>
ただ個人的には，情報収集ツールとして見たときのtwitterは，時間の使い方として無駄が多いんじゃないかという気がしています．
(まだあまりtwitterを使っていないので，これから認識が変わるかも知れませんが．．．)
</p>
<p>
あくまでこんな感じかなと思っています．
</p>
<ul>
<li>情報収集ツール - 従来通りRSS+RSSアグリゲータ (俺の場合はbloglinesと自作RSSリーダの<a title="RSSで全文配信する" href="http://kamoland.com/wiki/wiki.cgi?RSS%A4%C7%C1%B4%CA%B8%C7%DB%BF%AE%A4%B9%A4%EB">組み合わせ</a>)</li>
<li>どうでもいい雑談など - twitter</li>
</ul>]]></content:encoded>
    <dc:date>2009-10-03T15:51:59+09:00</dc:date>
    <dc:subject>RSS</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0">
    <title>WikiにDisqusを組み込む</title>
    <link>http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0</link>
    <description>便利そうなので，Disqusコメントシステムをカモランド(PyukiWikiベース)に組み込んだ．デザインのカスタマイズや日本語化についての苦労話．</description>
    <content:encoded><![CDATA[<p>
便利そうなので，Disqusコメントシステムをカモランド(<a title="PyukiWiki" href="http://kamoland.com/wiki/wiki.cgi?PyukiWiki">PyukiWiki</a>ベース)に組み込んだ．デザインのカスタマイズや日本語化についての苦労話．

<div>
<a id="contents_1"></a>
<ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i0">WikiにDisqusを組み込む</a></li>

<ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i1">１．日本語化</a></li>

<ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i2">ボタン類の日本語化</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i3">メッセージの強制差し替え</a></li>

</ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i4">２．デザインのカスタマイズ</a></li>

<ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i5">テーマの選び方</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i6">コメント入力欄以外のカスタマイズ</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i7">コメント入力欄(iframe)のカスタマイズ</a></li>

</ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i8">３．ページのエンコーディングがUTF-8で無い場合の注意</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i9">４．ここまでのまとめ</a></li>

<ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i10">DISQUSの設定</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i11">Disqusを設置しているページのHTML記述</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i12">投稿欄に適用する外部CSS</a></li>

</ul>
<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i13">５．Disqusの変な自画面リロードURLへの対策</a></li>

<li><a href="?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0#i14">参考</a></li>

</ul>
</ul></div>

</p>
<h2><a name="i0"> </a>WikiにDisqusを組み込む</h2>
<a href="http://disqus.com/">Disqus</a> は訪問者コメントの仕組みを提供していて，JavaScriptインクルードで簡単にサイトに組み込むことができる．
今時のサービスを知るために，カモランドに組み込んでみた．
<p>
※現在は，カモランドから除去してあります．カモランドでは，サイトの閲覧者に大量にJSを読み込んでもらう負担を強いてまで設置しておく価値は無いと判断しました (2010/2/14)
</p>
<div></div><h3><a name="i1"> </a>１．日本語化</h3>
日本語Webサイトのコメント入力部が英語というのはまず考えられないので，日本語にする．
<div></div><h4><a name="i2"> </a>ボタン類の日本語化</h4>
まずはボタン類の日本語化で，これは簡単．Disqusの管理画面で，サイトの設定(General > Basic Settings)をLanguage=Japaneseにすれば良い．
<p>
ただし，デザインのテーマを「Narcissus」にしていると効かないので注意．これで数時間ハマった．Classicにするべし．
Narcissusは他にも，iframe用CSSファイルを設定できないという問題があるので，使い物にならないと思う．
</p>
<p>
これで，
</p>
<ul>
<li>ネーム</li>
<li>メールアドレス</li>
<li>ウェブサイト</li>
<li>ボタン「コメント入力」/「XXXのユーザ名で入力」</li>
という風に日本語のメッセージが出るようになる．
</ul>
<p>
ちなみにNarcissusだと，こんな感じの中途半端な日本語化になった．
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=narcissus.png&amp;mypage=Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0&amp;refer=Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0" title="narcissus.png"><img src="http://kamoland.com/wiki/attach/57696B69A4CB446973717573A4F2C1C8A4DFB9FEA4E0_6E61726369737375732E706E67" alt="narcissus.png" title="narcissus.png" width="318.75" height="231" /></a>
</p>
<div></div><h4><a name="i3"> </a>メッセージの強制差し替え</h4>
しかし困ったことに，まだこんなメッセージが出る．
<div>
<pre>
You are commenting as a Guest. You may select one to log into:
</pre>
</div>
disqusの設定をくまなく探したが，これは変更できなさそうだ．そこで，JavaScriptで強制的にHTMLを書き換えることにした．
<div>
<pre>
var disqus_my_customize_retry = 10;
function disqus_my_customize() {
	if( ! document.getElementById('dsq-login-message')) {
		if (--disqus_my_customize_retry > 0) {
			window.setTimeout('disqus_my_customize()',1000);
		}
		return;
	}
	document.getElementById('dsq-login-message').innerHTML =
'Disqus，Twitterのアカウントがある人は，下のボタンでログインすればその名義で書き込みできます．' +
'ただしブラウザが第三者のクッキー許可の設定になっていない場合は，ログインできません．&lt;br&gt;' +
'ログインしない場合は「ネーム」と「メールアドレス」が入力必須になりますが，' +
'メールアドレスは表示も公開もされません';
}

&lt;script type="text/javascript" src="http://disqus.com/forums/kamoland/embed.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
disqus_my_customize();
&lt;/script&gt;
</pre>
</div>
やっていることは，embed.jsを取り込んだあとで，要素'dsq-login-message'のinnerHTMLを書き換えて，
メッセージを変えているだけ．ただ，この要素がいつ構築されるのかがわからないので，タイマーでリトライして構築されるのを待っている．
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=disqus_login_mes.png&amp;mypage=Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0&amp;refer=Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0" title="disqus_login_mes.png"><img src="http://kamoland.com/wiki/attach/57696B69A4CB446973717573A4F2C1C8A4DFB9FEA4E0_6469737175735F6C6F67696E5F6D65732E706E67" alt="disqus_login_mes.png" title="disqus_login_mes.png" width="322.5" height="162.75" /></a>
<p>
目を覆うばかりのダサダサ方式だが，まぁできているから良しとする．
</p>
<div></div><h3><a name="i4"> </a>２．デザインのカスタマイズ</h3>
<div></div><h4><a name="i5"> </a>テーマの選び方</h4>
Narcissusは使い物にならない．
<ul>
<li>日本語対応していない</li>
<li>iframe用CSSファイル設定ができない</li>
</ul>
<p>
なので，Classicから選ぶべし．うちはClassic Aにした．なお，iframe用CSSファイルについては後述．
</p>
<div></div><h4><a name="i6"> </a>コメント入力欄以外のカスタマイズ</h4>
コメント入力欄以外は，disqusの設定の「Custom CSS」にCSSを書き込めば簡単．FireBugを使って地道に，スタイルを変えたい要素のidやclassを調べて，
それにスタイルを当てればよい．
カモランドでは，こういう内容を設定している．
<div>
<pre>
h3#dsq-comments-count { display: none; }
div#dsq-options { display: none; }
div.dsq-likedtxt {display:none;}
li.dsq-rate {display:none !important;}
li.dsq-report {display:none !important;}
h3#dsq-add-new-comment {
	font-size:100%;
	background-color:#606070;
 	color: #ffffff;
	font-weight:bold;
	padding: .2em 0px .5em 1em;
	border: 0px;
	margin: 0px 0px 0.2em 0px;
	width:400px;
}
div#disqus_thread {
	width: 400px;
	float: left;
	margin-top: 2em;
}
</pre>
</div>
<div></div><h4><a name="i7"> </a>コメント入力欄(iframe)のカスタマイズ</h4>
FireBugでDOMを探索すると気づくが，肝心のコメント入力欄の部分はiframeでdisqus.comから読み込まれている．
ヒェー，CSSを当てれない！？
<p>
それでdisqusのドキュメントを調べると，
</p>
<ul>
<li><a href="http://disqus.com/docs/embed/">DISQUS | JavaScript Embed Overrides</a></li>
</ul>
<p>
JavaScriptのパラメータで
</p>
<ul>
<li>disqus_iframe_css</li>
</ul>
<p>
を使って外部CSSのURLを指定すれば，それがコメント欄のiframeに適用されるということだ．
これを使えば問題ない．
</p>
<p>
カモランドではこんな感じで設定して，レイアウトを圧縮している．URLの入力欄は邪魔なので消している．
</p>
<div>
<pre>
★ HTML本体
&lt;script type="text/javascript"&gt;
var disqus_iframe_css = "http://kamoland.com/wiki/skin/disqus_iframe.css";
&lt;/script&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/kamoland/embed.js"&gt;&lt;/script&gt;

★ disqus_iframe.css
form#comment-form textarea {height:4em;}
div#form-block-name {}
div#form-block-email {}
div#form-block-url {display:none;}
div#form-block-submit {}
</pre>
</div>
<div></div><h3><a name="i8"> </a>３．ページのエンコーディングがUTF-8で無い場合の注意</h3>
ページがUTF-8なら気にする必要はないが，sjis(Shift-JIS)とかカモランドのようにEUC-JPの場合は，
注意が必要．
<p>
disqusはデフォルトで，そのページ&lt;title&gt;タグの文字列をタイトルとして扱うが，
文字コードがUTF-8以外の場合，以下のような症状が出る (というか，出た)
</p>
<ul>
<li>DISQUSのコミュニティ画面(<a href="http://kamoland.disqus.com/">http://kamoland.disqus.com/</a> など)で，ページ名が文字化け状態</li>
<li>DISQUSのコメント欄が出ないページがある．FireBugでiframe内を見ると，disqusがエラーを出していた</li>
</ul>
<div>
<pre>
&lt;title&gt;DISQUS | Error (500)&lt;/title&gt;
・・・中略・・・
&lt;h3&gt;Sorry, an error occurred on our end.&lt;/h3&gt;
&lt;p&gt;We've been notified of the issue and are on the case.&lt;/p&gt;
</pre>
</div>
エラーメッセージが全然あてにならないので試行錯誤を強いられたが，結局，JavaScriptのパラメータ
<ul>
<li>disqus_title</li>
</ul>
<p>
をUnicodeで設定すればこれは解決した．(設定しない場合のデフォルトは，&lt;title&gt;タグの内容)
</p>
<p>
カモランドではこんな感じで，ページタイトルのUTF-16を，エンコードした表記を使ってパラメータを設定しています．
</p>
<div>
<pre>
var disqus_title = "\u0057\u0069\u006B\u0069\u306B\u0044\u0069\u0073\u0071\u0075\u0073\u3092\u7D44\u307F 〜";
</pre>
</div>
このエンコード表記の生成は，Wikiのperlで処理しています．
<p>
しかしもし，CGIやPHPでない静的HTMLのページだと，どうするんだろうか？．．．
</p>
<p>
JavaScriptでどの程度文字コード変換ができるのか知らないが，
静的HTMLでsjis(Shift-JIS)やEUC-JPを使っているというパターンだと，disqusを使うのは無理かもしれないな．
</p>
<p>
最悪，&lt;title&gt;を，UTF-8でもそれ以外でもコードが変わらないASCII文字(英数字)だけでつければ化けないだろうが，それは閲覧者にやさしくないし．(SEO的にも．．．)
</p>
<p>
また，
</p>
<ul>
<li>サイト管理者に送られてくる投稿通知メールのタイトル</li>
<li>投稿者が自分の過去の投稿を閲覧できる画面(<a href="http://disqus.com/kamo/">http://disqus.com/kamo/</a> など)で表示される，ページ名</li>
</ul>
<p>
にも同じようにタイトルが使われているため，disqus_titleを設定しないとここでも文字化けが発生します．
</p>
<p>
★ (2009.10.31 追記) さらにその後，いつの間にかコメント入力欄にこんな文字化けが出るようになった．
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=comment_mojibake.jpg&amp;mypage=Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0&amp;refer=Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0" title="comment_mojibake.jpg"><img src="http://kamoland.com/wiki/attach/57696B69A4CB446973717573A4F2C1C8A4DFB9FEA4E0_636F6D6D656E745F6D6F6A6962616B652E6A7067" alt="comment_mojibake.jpg" title="comment_mojibake.jpg" width="330" height="104" /></a>
</p>
<p>
thread.jsのソースを調べたところ，disqus_default_textを設定すれば，ここの文字列を変えることができることが判明した．
</p>
<p>
カモランドではこんな感じで半角スペースを設定し，文字化けにならないようにしています．
</p>
<div>
<pre>
var disqus_default_text = " ";
</pre>
</div>
本来は「ここにコメントを入力」というのを適当な文字コードで設定すればいいんでしょうが，
めんどくさくなりました．
<p>
ここまでの「UTF-8で無い場合の注意」をまとめると，こんな感じになります．
</p>
<table cellspacing="1" border="1">
<tr><th>JavaScript変数名</th><th>設定内容</th><th>解消される問題</th></tr>
<tr><td>disqus_title</td><td>ページタイトルをUTF-16で表記したもの</td><td>コミュニティ画面のタイトル文字化け，投稿通知メールのタイトル文字化け，投稿者プロファイル画面での投稿一覧のタイトル文字化け ※disqus_titleが実際にDISQUSのサーバに反映されるにはかなり時間がかかるようです．数週間かかっても反映されないページもあります</td></tr>
<tr><td>disqus_default_text</td><td>半角スペース</td><td>コメント入力欄の初期表示の文字化け</td></tr>
</table>
<div></div><h3><a name="i9"> </a>４．ここまでのまとめ</h3>
カモランドの場合の設定例です
<div></div><h4><a name="i10"> </a>DISQUSの設定</h4>
<ul>
<li>デザインテーマ = Classic A</li>
</ul>
<p>
<span>Custom CSS</span>
</p>
<div>
<pre>
/* 投稿欄の周りの部分のカスタマイズ */
h3#dsq-comments-count { display: none; }
div#dsq-options { display: none; }
div.dsq-likedtxt {display:none;}
li.dsq-rate {display:none !important;}
li.dsq-report {display:none !important;}
h3#dsq-add-new-comment {
	font-size:100%;
	background-color:#606070;
 	color: #ffffff;
	font-weight:bold;
	padding: .2em 0px .5em 1em;
	border: 0px;
	margin: 0px 0px 0.2em 0px;
	width:400px;
}
div#disqus_thread {
	width: 400px;
	float: left;
	margin-top: 2em;
}
</pre>
</div>
<div></div><h4><a name="i11"> </a>Disqusを設置しているページのHTML記述</h4>
<span>Disqusを設置しているページのHTMLソースの例</span>
<div>
<pre>
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
// 英語のメッセージを日本語メッセージに強制書き換え
var disqus_my_customize_retry = 10;
function disqus_my_customize() {
	if( ! document.getElementById('dsq-login-message')) {
		if (--disqus_my_customize_retry > 0) {
			// DISQUSの要素が構築されるまでリトライする
			window.setTimeout('disqus_my_customize()',1000);
		}
		return;
	}
	document.getElementById('dsq-login-message').innerHTML =
'Disqus，Twitterのアカウントがある人は，下のボタンでログインすればその名義で書き込みできます．ただしブラウザが第三者のクッキー許可の設定になっていない場合は，ログインできません．&lt;br&gt;ログインしない場合はメッセージは管理者が承認するまで公開されません．また「ネーム」と「メールアドレス」が入力必須になりますが，メールアドレスは表示も公開もされません';
}
// ページのURL
var disqus_url = "http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CBDisqus%A4%F2%C1%C8%A4%DF%B9%FE%A4%E0";

// 投稿欄をカスタマイズするための外部CSS
var disqus_iframe_css = "http://kamoland.com/wiki/skin/disqus_iframe.css";

// ページの文字コードがUTF-8でない場合は，これらを設定しないと文字化けする
// ページのタイトル (通常は&lt;title&gt;の内容)
var disqus_title = "\u0057\u0069\u006B\u0069\u306B\u0044\u0069\u0073\u0071\u0075\u0073\u3092\u7D44\u307F\u8FBC\u3080\u0020\u002D\u0020\u004B\u0061\u006D\u006F\u004C\u0061\u006E\u0064";
// ページの説明
var disqus_message = "\u4FBF\u5229\u305D\u3046\u306A\u306E\u3067\uFF0C\u0044\u0069\u0073\u0071\u0075\u0073\u30B3\u30E1\u30F3\u30C8\u30B7\u30B9\u30C6\u30E0\u3092\u30AB\u30E2\u30E9\u30F3\u30C9\u0028\u0050\u0079\u0075\u006B\u0069\u0057\u0069\u006B\u0069\u30D9\u30FC\u30B9\u0029\u306B\u7D44\u307F\u8FBC\u3093\u3060\uFF0E\u30C7\u30B6\u30A4\u30F3\u306E\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA\u3084\u65E5\u672C\u8A9E\u5316\u306B\u3064\u3044\u3066\u306E\u82E6\u52B4\u8A71\uFF0E";
// コメント入力欄が空の時に表示する文字列 (本来は「ここにコメントを入力」だったもの)
var disqus_default_text = " ";

// メッセージ強制書き換えの呼び出し
disqus_my_customize();
&lt;/script&gt;

// DISQUSのJavaScript取り込み
&lt;script type="text/javascript" src="http://disqus.com/forums/kamoland/embed.js"&gt;&lt;/script&gt;
</pre>
</div>
<div></div><h4><a name="i12"> </a>投稿欄に適用する外部CSS</h4>
<span>http://kamoland.com/wiki/skin/disqus_iframe.css</span>
<div>
<pre>
/* 投稿欄のカスタマイズ */
form#comment-form textarea {height:4em;} /* コメント欄の高さを縮小 */
div#form-block-name {}
div#form-block-email {}
div#form-block-url {display:none;} /* URL入力欄は表示しない */
div#form-block-submit {}
</pre>
</div>
<div></div><h3><a name="i13"> </a>５．Disqusの変な自画面リロードURLへの対策</h3>
ここからは，Wikiというか<a title="PyukiWiki" href="http://kamoland.com/wiki/wiki.cgi?PyukiWiki">PyukiWiki</a>独特の話になる．
<p>
Disqusでは，
</p>
<ul>
<li>投稿時</li>
<li>ログイン時</li>
</ul>
<p>
に，なんか処理したり第三者クッキーを設定したりしたあと現在の画面を再読み込みする．
このとき，URLの後ろに変なパラメータが付いてくるので，<a title="PyukiWiki" href="http://kamoland.com/wiki/wiki.cgi?PyukiWiki">PyukiWiki</a>が誤動作するという問題が起きた．
</p>
<p>
<span>付いたパラメータの具体例</span>
</p>
<div>
<pre>
【投稿時】&amp;dsq=16909359#comment-16909359
【ログイン時】&amp;success
</pre>
</div>
それでWiki側の実装を改造して，これらのパラメータが付いたURLを要求されたときは，
これらのパラメータを削ったURLにリダイレクトするようにしておいた．
<div></div><h3><a name="i14"> </a>参考</h3>
<ul>
<li><a href="http://www.atmarkit.co.jp/news/analysis/200903/09/social.html">「通りすがり」コメントの終焉 − ＠IT</a></li>
<li><a href="http://disqus.com/developers/">DISQUS | Developers</a></li>
</ul>]]></content:encoded>
    <dc:date>2009-09-19T20:34:56+09:00</dc:date>
    <dc:subject>CMS</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%282%29">
    <title>キーワード抽出による関連ページ導出(2)</title>
    <link>http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%282%29</link>
    <description>Webページから単語抽出して遊ぼう．前回は，キーワードとしてふさわしくないような単語まで抽出されて，頭を抱えたところで終わった．今回はそのページに検索エンジンでの検索で使われたキーワードを取得して使ってみる．【更新】対象の検索エンジンにBingを追加しました (2009-08-01)</description>
    <content:encoded><![CDATA[<p>
Webページから単語抽出して遊ぼう．<a title="キーワード抽出による関連ページ導出" href="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0">前回</a>は，キーワードとしてふさわしくないような単語まで抽出されて，頭を抱えたところで終わった．今回はそのページに検索エンジンでの検索で使われたキーワードを取得して使ってみる．

</p>
<p>
<div><span>2009-08-01</span> 対象の検索エンジンにBingを追加しました</div>

<div><span>2008-03-02</span> 初版</div>

</p>
<p>
この状況を何とかしようとして普通に考えると，
</p>
<ul>
<li>キーワードとしてふさわしい単語のリスト(辞書)を整備する</li>
</ul>
<p>
ということになるが，これは終わりのない面倒な作業だ．
</p>
<p>
そこで，
</p>
<ul>
<li>カモランドへのアクセスは，検索エンジン経由が圧倒的に多い</li>
</ul>
<p>
という事実に着目した．
<div style="float:left;padding:.5em 1.5em .5em 1.5em">
 <img src="http://kamoland.com/blog/archives/blog20080302a.png" alt="" />
</div>

<div style="clear:both"></div>
　↑Google Analyticsによるカモランドのリファラーのグラフ
</p>
<p>
検索エンジン経由で来てそのページが表示されたということは，そこで使われた検索キーワードはそのページに関係が深いはず(検索エンジンはそういう風に作られている)なので，その検索キーワードをそのページを代表するキーワードだと考えても，おかしくないはずだ．
</p>
<p>
すると，そもそもの目的の「関連ページを表示する」を考えたとき，
</p>
<ul>
<li>サイト内で，そのキーワードを含む他のページが，そのページと関連があるページだ</li>
</ul>
<p>
と言えるのではなかろうか．
</p>
<p>
そこで，検索エンジン経由でカモランドのページに到達した場合は，検索で使われたキーワードを含むページを，そのページの関連ページと見なして下部に表示するようにしてみた．
</p>
<p>
具体的には，<a href="http://www.google.com/search?q=redhat+oracle&amp;sourceid=ie7&amp;rls=com.microsoft:en-US&amp;ie=utf8&amp;oe=utf8">「redhat oracle」というキーワードでGoogleで検索する</a> と，カモランド(プログラマー'sペイジ)のページが上位あたり(今日は2位)に出るが，そのリンクをクリックして表示されたカモランドのページでは，関連ページの表示部が
</p>
<div>
<pre>
このサイト内の関連ページ (redhat oracle)
</pre>
</div>
という風にキーワード検索の結果になっているのです．
まぁ，LPO(ランディングページ最適化)もどきですわ．
<p>
あと、日本語文字の検索語への対応については、少し考える必要がある。検索語のエンコーディングが不定なので、動的な文字コード判定を組み込む必要がある．
例えば，GoogleならリファラーURLのパラメータieにエンコーディングが含まれているとかいう話で、これを他の検索エンジンについても調べる必要がある。
</p>
<p>
ちょっと、Apacheの過去ログを眺めたり実サイトで実際に叩いたりして，調べてみた．
</p>
<table cellspacing="1" border="1">
<tr><th>検索エンジン名</th><th>エンコパラメータ名</th><th>無指定時のエンコ</th><th>備考</th></tr>
<tr><td>Google</td><td>ie</td><td>UTF-8 or Shift_JIS</td><td></td></tr>
<tr><td>Yahoo</td><td>ei</td><td>UTF-8 or EUC-JP</td><td></td></tr>
<tr><td>Bing</td><td>-</td><td>UTF-8</td><td></td></tr>
<tr><td>LiveSearch</td><td>cp</td><td>UTF-8</td><td>cp=932(ほぼShift_JIS)のみ確認</td></tr>
<tr><td>MSN</td><td>cp</td><td>UTF-8</td><td>cp=932(ほぼShift_JIS)のみ確認</td></tr>
<tr><td>goo</td><td>ie</td><td>EUC-JP</td><td></td></tr>
<tr><td>Infoseek</td><td>-</td><td>UTF-8 or EUC-JP</td><td></td></tr>
<tr><td>nifty(昔)</td><td>ie</td><td>Shift_JIS or EUC-JP</td><td>パスは/cgi-bin/</td></tr>
<tr><td>nifty</td><td>-</td><td>UTF-8</td><td>パスは/websearch/</td></tr>
<tr><td>biglobe</td><td>-</td><td>Shift_JIS or EUC-JP</td><td></td></tr>
<tr><td>Mooter</td><td>-</td><td>UTF-8</td><td></td></tr>
</table>
<p>
カモランドで収集した情報だけなので、漏れがあると思います。今のところ、これらの情報を使って文字コードを判別するようにすることで、日本語のキーワードも正しく扱えているようだ。
</p>
<p>
なおRubyによる実装が、<a title="Rubyでrefererから検索キーワードを抽出する" href="http://kamoland.com/wiki/wiki.cgi?Ruby%A4%C7referer%A4%AB%A4%E9%B8%A1%BA%F7%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%A4%F2%C3%EA%BD%D0%A4%B9%A4%EB">Rubyでrefererから検索キーワードを抽出する</a>にあります。
</p>
<p>
[参考]
</p>
<ul>
<li><a href="http://www.magicvox.net/archive/2007/04122238">JavaScriptで検索ワードをハイライトする - Open MagicVox.net</a></li>
<li><a href="http://scott.yang.id.au/2004/06/se-hilite/">Search Engine Keyword Highlight with Javascript | SYP</a></li>
</ul>]]></content:encoded>
    <dc:date>2009-08-01T20:18:45+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB">
    <title>GeoRSSでGoogleMapと連携する</title>
    <link>http://kamoland.com/wiki/wiki.cgi?GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB</link>
    <description>GeoRSSを使って，吹き出しマークを出した状態でGoogle Mapを開けるようにした．</description>
    <content:encoded><![CDATA[<p>
GeoRSSを使って，吹き出しマークを出した状態でGoogle Mapを開けるようにした．

</p>

<h2><a name="i0"> </a>GeoRSSでGoogleMapと連携する</h2>
最近，風景写真集のページに行程表と地図を入れていて，一緒にGoogle Mapへのリンクも付けていたのだが，
機能としては単にノッペリとそのエリアのGoogle Mapが開くだけで，いまいちだった．
<p>
もう少しましな連携ができないかと調べたところ，GoogleMapは外部の<a href="http://georss.org/">GeoRSS</a>
のファイルを読むことができることがわかった．
</p>
<p>
GeoRSSは，RSS，Atomで使える語彙の一つで，
</p>
<ul>
<li>点 (1点で構成)</li>
<li>線 (2点以上で構成)</li>
<li>ボックス (対角の2点で構成)</li>
<li>ポリゴン (4点以上で構成)</li>
</ul>
<p>
を表現できるらしい．
</p>
<p>
こういう語彙っていうのは，それ自体はあまり重要ではなく，「広く使われているかどうか？」が重要なのだが，
Googleが使っているというのはその点非常に強力だ．
</p>
<div></div><h3><a name="i1"> </a>GeoRSSの書き方</h3>
今回使ったのは一番簡単な点の指定．まず
<div>
<pre>
xmlns:georss="http://www.georss.org/georss"
</pre>
</div>
で名前空間georssを宣言して，こんな感じで点を記述する．
<div>
<pre>
&lt;georss:point&gt;35.272298 136.263111&lt;/georss:point&gt;
</pre>
</div>
<ul>
<li>世界測地系WGS84の 緯度，経度の順で</li>
<li>半角スペースまたはカンマで区切って</li>
</ul>
<p>
記述すれば良い．最初，間違って経度，緯度の順で記述してたら，Google Mapでエラーが出続けてはまった．
</p>
<div></div><h3><a name="i2"> </a>RSS 1.0として記述する例</h3>
Google Mapの動きを見ていると，RSSに記述する各アイテムの属性はこんな感じの使われ方をしている．
<table cellspacing="1" border="1">
<tr><th>属性</th><th>GoogleMap左パネル部</th><th>GoogleMap地図部</th></tr>
<tr><td>title</td><td>見出しとして出る</td><td>吹き出しのタイトル</td></tr>
<tr><td>link</td><td></td><td>吹き出しのタイトルのリンク先</td></tr>
<tr><td>description</td><td>先頭1行程度が見出しの下に出る</td><td>吹き出し内に全文が出る．HTMLタグは有効</td></tr>
<tr><td>dc:creator</td><td>-</td><td>吹き出しのタイトルの下に作成者として出る</td></tr>
<tr><td>georss:point</td><td>-</td><td>マーカーの座標</td></tr>
</table>
<p>
※dcは，Dublin Coreの語彙
</p>
<p>
なので，今回のGoogle Map連携だけの用途なら，最低限
</p>
<ul>
<li>title</li>
<li>link</li>
<li>description</li>
<li>georss:point</li>
</ul>
<p>
を設定すれば良さそうだ．
</p>
<p>
<span>GeoRSSの例．item1個だけ抜粋</span>
</p>
<div>
<pre>
&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:georss="http://www.georss.org/georss"
>

&lt;channel rdf:about="http://kamoland.com"&gt;
 &lt;title&gt;琵琶湖サイクリング(2009年5月)&lt;/title&gt;
 &lt;link&gt;http://kamoland.com&lt;/link&gt;
 &lt;description&gt;&lt;/description&gt;
 &lt;items&gt;
  &lt;rdf:Seq&gt;
   &lt;rdf:li rdf:resource="http://kamoland.com/wiki/wiki.cgi?%C8%FC%C7%CA%B8%D0%A5%B5%A5%A4%A5%AF%A5%EA%A5%F3%A5%B0%282009%C7%AF5%B7%EE%29#mk1" /&gt;
  &lt;/rdf:Seq&gt;
 &lt;/items&gt;
&lt;/channel&gt;
   &lt;item rdf:about="http://kamoland.com/wiki/wiki.cgi?%C8%FC%C7%CA%B8%D0%A5%B5%A5%A4%A5%AF%A5%EA%A5%F3%A5%B0%282009%C7%AF5%B7%EE%29#mk1"&gt;
    &lt;title&gt;01. 彦根駅出発&lt;/title&gt;
    &lt;link&gt;http://kamoland.com/wiki/wiki.cgi?%C8%FC%C7%CA%B8%D0%A5%B5%A5%A4%A5%AF%A5%EA%A5%F3%A5%B0%282009%C7%AF5%B7%EE%29#mk1&lt;/link&gt;
    &lt;description&gt;9:40 彦根駅出発&lt;/description&gt;
    &lt;dc:date&gt;&lt;/dc:date&gt;
    &lt;dc:subject&gt;&lt;/dc:subject&gt;
    &lt;georss:point&gt;35.272298 136.263111&lt;/georss:point&gt;
   &lt;/item&gt;
&lt;/rdf:RDF&gt;
</pre>
</div>
なお，&lt;description&gt;にHTMLを記述すると吹き出し内では有効なので，&lt;img&gt;タグを使って吹き出しに画像を出すことも可能．
<p>
<span>画像を出す例</span>
</p>
<div>
<pre>
&lt;description&gt;TEST &amp;lt;img src="http://kamoland.com/image/blog.jpg" width="212" height="83"&amp;gt;&lt;/description&gt;
</pre>
</div>
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=georss1.jpg&amp;mypage=GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB&amp;refer=GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB" title="georss1.jpg"><img src="http://kamoland.com/wiki/attach/47656F525353A4C7476F6F676C654D6170A4C8CFA2B7C8A4B9A4EB_67656F727373312E6A7067" alt="georss1.jpg" title="georss1.jpg" width="400" height="283" /></a>

<div></div><h3><a name="i3"> </a>カモランドでの連携の仕組み</h3>
カモランドでは，行程表のGeoRSSをCGIで動的に生成するようにしたので，
GoogleMapに対しては，そのCGIのURLを渡している．
<p>
<span>CGIのURL</span>
</p>
<div>
<pre>
http://kamoland.com/wiki/wiki.cgi?cmd=rss10koutei&amp;p=%C8%FC%C7%CA%B8%D0%A5%B5%A5%A4%A5%AF%A5%EA%A5%F3%A5%B0%282009%C7%AF5%B7%EE%29
</pre>
</div>
<p>
<span>Google MapへのリンクURL</span>
</p>
<div>
<pre>
http://maps.google.com/maps?f=q&amp;hl=ja&amp;ie=UTF8&amp;q=http%3A%2F%2Fkamoland.com%2Fwiki%2Fwiki.cgi%3Fcmd%3Drss10koutei%26p%3D%25C8%25FC%25C7%25CA%25B8%25D0%25A5%25B5%25A5%25A4%25A5%25AF%25A5%25EA%25A5%25F3%25A5%25B0%25282009%25C7%25AF5%25B7%25EE%2529
</pre>
</div>
<span>リンク先で開いたGoogleMap</span>
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=georss2.jpg&amp;mypage=GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB&amp;refer=GeoRSS%A4%C7GoogleMap%A4%C8%CF%A2%B7%C8%A4%B9%A4%EB" title="georss2.jpg"><img src="http://kamoland.com/wiki/attach/47656F525353A4C7476F6F676C654D6170A4C8CFA2B7C8A4B9A4EB_67656F727373322E6A7067" alt="georss2.jpg" title="georss2.jpg" width="600" height="404" /></a>
<p>
ふぅ，とりあえずこれで満足，満足 (￣ー￣)
</p>
<p>
もっと凝ったことをやろうとするとGoogle Maps APIが要るんだろうけど，メインは電子国土なのでそこまで深入りする気はない．(多分)
</p>]]></content:encoded>
    <dc:date>2009-05-30T22:18:45+09:00</dc:date>
    <dc:subject>RSS</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%283%29">
    <title>キーワード抽出による関連ページ導出(3)</title>
    <link>http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%283%29</link>
    <description>フッタ部に関連ページを表示する方法を改善した．そのページと同じキーワードで過去に検索エンジン経由でアクセスされたページ，を出す方法を試した．</description>
    <content:encoded><![CDATA[<p>
フッタ部に関連ページを表示する方法を改善した．そのページと同じキーワードで過去に検索エンジン経由でアクセスされたページ，を出す方法を試した．

</p>
<p>
<a title="キーワード抽出による関連ページ導出(2)" href="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%282%29">前回</a>，そのページが検索エンジンからどういうキーワードで検索されてアクセスされたのかを調べた．
そして「その単語を含むカモランド内の他のページ」が，関連性の高いページだろうと考えたのだが，どうも見ているといまいち精度が悪い．
</p>
<p>
それで今回は，単純にその単語を含むページではなく
</p>
<ul>
<li>その単語を使った検索で，過去に検索エンジンの検索結果からアクセスされたことがあるページ</li>
</ul>
<p>
を出すことを考えた．何やら話が込み入っているようだが，
</p>
<ol>
<li>今表示しているページを検索するために過去に使われたキーワードがXなら</li>
<li>過去に検索エンジンでXで検索した検索結果からアクセスされて表示されたことがあるページ(のうち今表示しているページ以外)を，関連ページとして表示する</li>
</ol>
<p>
という理屈．例えば<a title="キーワード抽出による関連ページ導出" href="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0">前々回</a>のページだと，こんな感じ．
</p>
<p>
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=keyword1.jpg&amp;mypage=%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%283%29&amp;refer=%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%283%29" title="keyword1.jpg"><img src="http://kamoland.com/wiki/attach/A5ADA1BCA5EFA1BCA5C9C3EABDD0A4CBA4E8A4EBB4D8CFA2A5DAA1BCA5B8C6B3BDD0283329_6B6579776F7264312E6A7067" alt="keyword1.jpg" title="keyword1.jpg" width="450" height="195" /></a>
</p>
<p>
この方法だと，ページの一覧を出すときにそのキーワードで検索された回数の多い順でソートすることで，
一種の人気順表示ができる．これはなかなか面白い．
</p>
<p>
難点は，
</p>
<ul>
<li>誰も検索エンジン経由でアクセスしてこなかったページには，表示できない</li>
</ul>
<p>
ということか．検索エンジンべったりの仕組みだ．
</p>
<p>
ちなみに技術的にはたいしたものではない．
</p>
<p>
Apacheのログデータにある各ページのリファラ(referer)から<a title="Rubyでrefererから検索キーワードを抽出する" href="http://kamoland.com/wiki/wiki.cgi?Ruby%A4%C7referer%A4%AB%A4%E9%B8%A1%BA%F7%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%A4%F2%C3%EA%BD%D0%A4%B9%A4%EB">検索キーワードを抽出</a>し，
それを使って処理している．Rubyのバッチで，毎朝この部分のHTMLデータを全ページ分生成している．
円グラフは，<a href="http://code.google.com/intl/ja/apis/chart/">Google Chart API</a> を使っている．
そしてカモランドのページを表示する時に，そのページに対応するHTMLデータをAjaxで差し込んでいる．
</p>
<p>
ページに静的に埋め込まずに動的に差し込んでいる理由は，ページ本体は<a title="mod_cacheでWiki(CGI)の高速化" href="http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%28CGI%29%A4%CE%B9%E2%C2%AE%B2%BD">Apache</a>と<a title="PyukiWikiにキャッシュ機能をつける" href="http://kamoland.com/wiki/wiki.cgi?PyukiWiki%A4%CB%A5%AD%A5%E3%A5%C3%A5%B7%A5%E5%B5%A1%C7%BD%A4%F2%A4%C4%A4%B1%A4%EB">Wiki</a>のキャッシュを最大限に効かせて表示したいため．
</p>]]></content:encoded>
    <dc:date>2009-03-29T22:05:41+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?BASIC%C7%A7%BE%DA%A4%CE%A5%D1%A5%B9%A5%EF%A1%BC%A5%C9%A4%CF8%CA%B8%BB%FA%A4%AB">
    <title>BASIC認証のパスワードは8文字か</title>
    <link>http://kamoland.com/wiki/wiki.cgi?BASIC%C7%A7%BE%DA%A4%CE%A5%D1%A5%B9%A5%EF%A1%BC%A5%C9%A4%CF8%CA%B8%BB%FA%A4%AB</link>
    <description>ApacheのBASIC認証で長いパスワードを使っていたが，デフォルトでは先頭の8文字までしか効いていなかった．</description>
    <content:encoded><![CDATA[<p>
ApacheのBASIC認証で長いパスワードを使っていたが，デフォルトでは先頭の8文字までしか効いていなかった．

</p>
<p>
ApacheのBASIC認証は，非SSLだともちろんセキュリティ的に使い物にならないが，SSLならまぁ使えるので，一応長いパスワードを設定して使っていた．
しかしどうも，途中までしか入力していなくてもなぜか認証に通ってしまうことに気づいた．
</p>
<p>
これはやばい，変だということで調べてみた．
</p>
<ul>
<li><a href="http://httpd.apache.org/docs/2.2/programs/htpasswd.html">Apache2.2マニュアル htpasswd</a></li>
</ul>
<p>
そこには衝撃の事実が記されていた．
</p>
<ul>
<li>Windows，Netware，TPF以外のプラットフォームでは，デフォルトでcrypt()関数の暗号化が使用される</li>
<li>crypt()関数の暗号化では，パスワードの先頭8文字だけが使われて，それより長い文字数の場合は切り捨てられる</li>
</ul>
<p>
ヽ(`Д´)ノ　　ガーン！
</p>
<p>
早速 -mオプションをつけて，crypt()ではなくMD5の暗号化でパスワードファイルを作り直した．
</p>
<div>
<pre>
/usr/local/apache2/bin/htpasswd -mc /usr/local/apache/conf/.dav davuser
</pre>
</div>
これで，長いパスワードを最後までちゃんと入れないと，認証に通らないようになった．めでたし．
<p>
あとMD5の他にも，-sオプションによるSHA方式もあるが，MD5に比べて生成される文字数が短いのと，マニュアルにランダムなSALTを使わないので強度が弱いと書かれているため，強度的にはMD5がベストのようだ．
</p>
<table cellspacing="1" border="1">
<tr><th>方式</th><th>htpasswdのオプション</th><th>備考</th></tr>
<tr><td>プレインテキスト</td><td>-p</td><td>Windows，Netware，TPFでしか使えない</td></tr>
<tr><td>crypt関数</td><td>-d</td><td>パスワードの先頭8文字のみ有効．Windows，Netware，TPFでは使えない．それ以外の環境ではこれがデフォルト</td></tr>
<tr><td>SHA</td><td>-s</td><td>ランダムなSALTを使わないので，総当たり攻撃に弱いらしい</td></tr>
<tr><td>MD5</td><td>-m</td><td>Windows，Netware，TPFでのデフォルト．強度的にはベスト</td></tr>
</table>]]></content:encoded>
    <dc:date>2009-03-17T21:34:43+09:00</dc:date>
    <dc:subject>Apache</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?Google%A5%B5%A5%A4%A5%C8%A5%DE%A5%C3%A5%D7%A4%CEURL%A5%A8%A5%F3%A5%B3%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0">
    <title>GoogleサイトマップのURLエンコーディング</title>
    <link>http://kamoland.com/wiki/wiki.cgi?Google%A5%B5%A5%A4%A5%C8%A5%DE%A5%C3%A5%D7%A4%CEURL%A5%A8%A5%F3%A5%B3%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0</link>
    <description>Webマスターツールでエラーが出ていたので調べると，どうもGoogleがサイトマップファイル(sitemap.txt)に要求しているURLのパーセントエンコーディングは，記号類の扱いでカモランドの想定とは違っているようだ．</description>
    <content:encoded><![CDATA[<p>
Webマスターツールでエラーが出ていたので調べると，どうもGoogleがサイトマップファイル(sitemap.txt)に要求しているURLのパーセントエンコーディングは，記号類の扱いでカモランドの想定とは違っているようだ．

</p>

<h2><a name="i0"> </a>GoogleサイトマップのURLエンコーディング</h2>
Google Webマスターツールで，また新たなエラーが出ていた．
<div>
<pre>
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
</pre>
</div>
Googleの説明によると，こういうことらしい．
<div>
<pre>
サイトマップの URL のサンプルをテストしたところ，一部の URL が別のページ
にリダイレクトされることがわかりました．サイトマップには，他の URL にリダ
イレクトされる URL ではなく，最終的なリンク先 (リダイレクト先) の URL を
指定するようお勧めします．
</pre>
</div>
このエラーの場合，正式なURLは
<div>
<pre>
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD%284%29
</pre>
</div>
なので，サイトマップ(sitemap.txt)に載せているURLは
<div>
<pre>
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD%284%29
</pre>
</div>
にしてあるのに，GoogleBotが
<div>
<pre>
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD(4)
</pre>
</div>
をGETするので，カモランド側で正式なURL
<div>
<pre>
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD%284%29
</pre>
</div>
に301リダイレクトしている状況．つまり，現象としては
<ul>
<li>サイトマップのURLとリダイレクト先のURLは一致するので正しいはずだが，GoogleBotがサイトマップとは違ったURLでアクセスしてくるため，結果として余計なリダイレクトが発生している</li>
</ul>
<p>
<div style="text-align:center"><a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=googlebot1.png&amp;mypage=Google%A5%B5%A5%A4%A5%C8%A5%DE%A5%C3%A5%D7%A4%CEURL%A5%A8%A5%F3%A5%B3%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0&amp;refer=Google%A5%B5%A5%A4%A5%C8%A5%DE%A5%C3%A5%D7%A4%CEURL%A5%A8%A5%F3%A5%B3%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0" title="googlebot1.png"><img src="http://kamoland.com/wiki/attach/476F6F676C65A5B5A5A4A5C8A5DEA5C3A5D7A4CE55524CA5A8A5F3A5B3A1BCA5C7A5A3A5F3A5B0_676F6F676C65626F74312E706E67" alt="googlebot1.png" title="googlebot1.png" width="823" height="289" /></a></div>

</p>
<p>
このリダイレクトを，Webマスターツールでは問題視している．
サイトマップファイルの不備だと怒られている．
</p>
<div></div><h3><a name="i1"> </a>GoogleBotがなぜ違ったURLでアクセスするのか？</h3>
GoogleBotは，パーセントエンコーディングを一部デコードしたURLに，アクセスしてきている．
この現象だけを見ると，このようにデコードされた文字については，元々エンコードせずにサイトマップに載せれば良いということになる．
具体的には，サイトマップのURLを，以下のように「(」「)」を含むものにすればよいはず．
<div>
<pre>
http://kamoland.com/wiki/wiki.cgi?mod_cache%A4%C7Wiki%A4%F2%B9%E2%C2%AE%B2%BD(4)
</pre>
</div>
しかし，この文字だけでよいのか，そもそもどういう規則なのかがわからない．
<p>
仕方がないので，<a href="http://www.ietf.org/rfc/rfc3986.txt">RFC-3986</a>をまじめに読むことにした．
</p>
<div></div><h3><a name="i2"> </a>以前読んだときの解釈</h3>
<a title="Wikiの長〜いURLがYSTのSEOになっている？" href="http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CE%C4%B9%A1%C1%A4%A4URL%A4%ACYST%A4%CESEO%A4%CB%A4%CA%A4%C3%A4%C6%A4%A4%A4%EB%A1%A9">以前</a>は，RFC3986を斜め読みしてそれっぽい箇所
<div>
<pre>
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
</pre>
</div>
を見つけ，ここに含まれる文字以外をパーセントエンコーディングすれば良いものだと思っていた．
しかしよく読むと，違った解釈の余地もありそうだ．
<div></div><h3><a name="i3"> </a>まじめに読み直す</h3>
今回問題となっている箇所は，URLの構成
<div>
<pre>
     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
</pre>
</div>
のうちの「query」の箇所だ．これは，
<div>
<pre>
3.4.  Query
query       = *( pchar / "/" / "?" )
</pre>
</div>
とのこと．内訳は，
<div>
<pre>
pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims  = "!" / "$" / "&amp;" / "'" / "(" / ")"
            / "*" / "+" / "," / ";" / "="
</pre>
</div>
となっているので，
queryには従来カモランドで許可としていたunreserved群以外にも，以下の文字が使えるらしい．
<div>
<pre>
sub-delims群 !$&amp;'()*+,;=
pchar追加分  :@
query追加分  /?
</pre>
</div>
つまり「(」「)」がURLのクエリー部に含まれるのは，間違いではないようだ．(= GoogleBotはおかしくはない)
<p>
しかし逆に「(」「)」を「%28」「%29」にパーセントエンコーディングした場合(カモランド方式)でも，
間違いというわけではないはずだが，
GoogleBotが方針としてURLのパーセントエンコーディングを最小限に抑えるということだと推測すれば，
まぁ辻褄があう．
</p>
<div></div><h3><a name="i4"> </a>URLエンコーディング方法の変更案</h3>
このGoogleBotの挙動を踏まえると，こういう実装案になる．
<div>
<pre>
以下の文字は生のまま残して，それ以外の文字をパーセントエンコーディングする
a-zA-Z0-9-._~!$'()*+,;:@/?
</pre>
</div>
「&amp;」「=」を除外しているのは，これは生のまま残すとWikiがパラメータの区切り文字として解釈するので，
誤動作してしまうためである．
RFC的には許されるが，アプリの入力仕様としては許されないという話．
<p>
<span>サイトマップ対応のURLエンコーディング実装案</span>
</p>
<div>
<pre>
・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 }" }
</pre>
</div>
．．．このエンコーディング法を使って生成したURLをサイトマップに載せれば，
おそらく問題は解決するのだと思われる．
<p>
しっかし正式なURLを移転するというのは，ソーシャルブックマーク対策の関係で気がすすまぬ．
しかもGoogleのためだけにとは ヽ(`Д´)ノ
</p>
<p>
結局，URLのエンコーディング法はそのままで，Googleサイトマップを使うのをやめた ヽ(`Д´)ノ　ヽ(`Д´)ノ
</p>]]></content:encoded>
    <dc:date>2009-03-04T19:24:20+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?GoogleBot%A4%CB302%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8%A4%CF%B6%D8%CA%AA">
    <title>GoogleBotに302リダイレクトは禁物</title>
    <link>http://kamoland.com/wiki/wiki.cgi?GoogleBot%A4%CB302%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8%A4%CF%B6%D8%CA%AA</link>
    <description>久しぶりに，Google Webマスターツールを開いてみると，カモランド内のページで，今までは出ていなかった「リダイレクト エラー」なるものが多発していた(118件)．</description>
    <content:encoded><![CDATA[<p>
久しぶりに，<a href="http://www.google.com/webmasters/sitemaps/?hl=ja">Google Webマスターツール</a>を開いてみると，カモランド内のページで，今までは出ていなかった「リダイレクト エラー」なるものが多発していた(118件)．

</p>
<p>
<a href="http://kamoland.com/wiki/wiki.cgi?cmd=attach&amp;pcmd=open&amp;file=wmtool1.jpg&amp;mypage=GoogleBot%A4%CB302%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8%A4%CF%B6%D8%CA%AA&amp;refer=GoogleBot%A4%CB302%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8%A4%CF%B6%D8%CA%AA" title="wmtool1.jpg"><img src="http://kamoland.com/wiki/attach/476F6F676C65426F74A4CB333032A5EAA5C0A5A4A5ECA5AFA5C8A4CFB6D8CAAA_776D746F6F6C312E6A7067" alt="wmtool1.jpg" title="wmtool1.jpg" width="600" height="358" /></a>
</p>
<p>
リダイレクトエラーと言われても心当たりはないので，<a href="https://www.google.com/support/webmasters/bin/answer.py?answer=35156&amp;ctx=tltp&amp;hl=ja">Googleの説明</a>を読んで，
指摘されたページの状況とつきあわせて思案したところ，どうも
</p>
<ul>
<li>302リダイレクトを使って別のURLに転送しているページが，リダイレクトエラーになっている</li>
</ul>
<p>
ということがわかった．カモランド内では，次のようなURLから正規のURLに誘導するためにリダイレクトを使っているが，
それが302リダイレクトだった．
</p>
<ul>
<li><a title="短縮URLについて" href="http://kamoland.com/wiki/wiki.cgi?%C3%BB%BD%CCURL%A4%CB%A4%C4%A4%A4%A4%C6">短縮URL</a></li>
<li>小文字でURLエンコーディングされている(=RFC3986違反の)URL (<a title="Wikiの長〜いURLがYSTのSEOになっている？" href="http://kamoland.com/wiki/wiki.cgi?Wiki%A4%CE%C4%B9%A1%C1%A4%A4URL%A4%ACYST%A4%CESEO%A4%CB%A4%CA%A4%C3%A4%C6%A4%A4%A4%EB%A1%A9">Wikiの長〜いURLがYSTのSEOになっている？</a>参照)</li>
</ul>
<p>
これはこれでまぁ納得．GoogleBotはそういうものなんですか．
</p>
<p>
．．．それはそうとして，果たして「リダイレクトエラー」なるものが一体どういう結果を招くのかがよくわからないので，
エラーが発生しているページをGoogleで検索してみた．すると．．．ヒットしない
</p>
<p>
何と，Googleのインデックスから消えているようだ．（（( ；ﾟДﾟ)))
</p>
<p>
これはいかんということで，早速301リダイレクトになるようにWikiのCGIを修正した．こういう感じの話．
</p>
<div>
<pre>
[変更前]
	print "Location: $new_url\n";
-----------------------
[変更後]
	print "Status: 301 Moved Permanently\n";  # ←追加
	print "Location: $new_url\n";
	print "\n";
</pre>
</div>
また，<a title="短縮URLの実装" href="http://kamoland.com/wiki/wiki.cgi?%C3%BB%BD%CCURL%A4%CE%BC%C2%C1%F5">短縮URL用のCGI</a>も合わせて修正させていただきましたので，リダイレクトエラー解消のほど，よろしくお願いいたします ＞ GoogleBot様
(；´Д｀)]]></content:encoded>
    <dc:date>2009-03-01T12:34:39+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?%B0%D9%C2%D8%A5%EC%A1%BC%A5%C8%A4%CERSS%A4%F2%C0%B8%C0%AE%A4%B9%A4%EB">
    <title>為替レートのRSSを生成する</title>
    <link>http://kamoland.com/wiki/wiki.cgi?%B0%D9%C2%D8%A5%EC%A1%BC%A5%C8%A4%CERSS%A4%F2%C0%B8%C0%AE%A4%B9%A4%EB</link>
    <description>前回，Bloglinesに溜めたRSSの記事をメールで受信できるようにした．せっかくなので，他にも毎日チェックするものとして為替レート情報もこの仕組みに載せようと考えて，為替レートのRSS配信機能を作成した．</description>
    <content:encoded><![CDATA[<p>
<a title="Bloglinesの記事をメールとして受け取る" href="http://kamoland.com/wiki/wiki.cgi?Bloglines%A4%CE%B5%AD%BB%F6%A4%F2%A5%E1%A1%BC%A5%EB%A4%C8%A4%B7%A4%C6%BC%F5%A4%B1%BC%E8%A4%EB">前回</a>，Bloglinesに溜めたRSSの記事をメールで受信できるようにした．せっかくなので，他にも毎日チェックするものとして為替レート情報もこの仕組みに載せようと考えて，為替レートのRSS配信機能を作成した．

</p>

<h2><a name="i0"> </a>為替レートのRSSを生成する</h2>
為替レートも，毎日チェックする情報としてBloglinesに読ませるためには，為替レートのRSSを用意する必要がある．
Web上にそのようなサービスもあるようだが，自動分析をやってみたい関係で，自前でRSSを生成することにした．

<div></div><h3><a name="i1"> </a>１．為替レートのRSS化</h3>
<a href="http://www.citibank.co.jp/JPGCB/NPA/acq/rates/fx_rate_JP.do">citibankの為替レートのページ</a>
のHTMLをwgetで取得して，
そのHTMLをperlで<a title="HTMLテキスト変換簡易スクリプト" href="http://kamoland.com/wiki/wiki.cgi?HTML%A5%C6%A5%AD%A5%B9%A5%C8%CA%D1%B4%B9%B4%CA%B0%D7%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">テキストに変換</a>するとこんな感じになるので，
<div>
<pre>
[ 2008/08/30 05:07	現在]
アメリカドル (USD)			 109.75	108.75	107.75
オーストラリアドル (AUD)	 94.60	93.60	 92.60
</pre>
</div>
ここからgrep的に通貨毎のレートを取得すればよい．簡単だ．
<p>
そしてこの内容を元にRSSを生成し，それをBloglinesで購読すればおしまい．
</p>
<ul>
<li><a href="http://kamoland.com/rss/kawase_test.xml">http://kamoland.com/rss/kawase_test.xml</a></li>
</ul>
<p>
これで，それぞれの通貨におけるその時点での仲値(TTM)を1日1回出力するという仕組みができた．
</p>

<div></div><h3><a name="i2"> </a>２．自動分析の実装</h3>
<div></div><h4><a name="i3"> </a>知りたい情報は何か？</h4>
しかしそれだけでは，RSSで配信された仲値を見ても「フーン」という感じで，ピンとこない．
最新の数字だけを見ても，それがどういう状況なのかいまいちよくわからない．
<p>
かといって，ニュースなどでよく見かけるように，前日との差(前日から+3ドル円安とか)を出してみたところで，あまり変わらない．
こういうのはチャートのグラフを見れば一目瞭然なんだが，RSSとしては何とかテキストで表現できるように工夫してみたい．
</p>
<p>
それで，俺なりに考えてみたのだが．．．
</p>
<p>
結局，何らかの行動を起こすきっかけは，おそらく「最近の傾向に比べて異常に高くなったか安くなった」というタイミングだと思うので，
このタイミングがわかるような情報を作れれば良いという結論に至った．
</p>
<p>
そのようなタイミングをどうやって求めるか？が問題になるが，
日経などの株式欄で見かける表現で，数字が黒く塗られていると年初来安値(その年の最安値)というのがある．
これは，現在からある程度過去にさかのぼった期間内で，最安値または最高値であれば，それは普通ではない(ので黒く塗って表現する)という発想なのだと思われる．
</p>
<p>
これと同じように考えて，
</p>
<ul>
<li>レートの過去データをさかのぼったときに，本日のレートがn日前以前の昔でないと現れない場合，そのレートは報告すべき異常値である</li>
</ul>
<p>
と見なすことにした．nが大きいほど重大で，例えばn=365なら「1年ぶりの安値」となる．
</p>

<div></div><h4><a name="i4"> </a>RSSへの組み込み</h4>
このロジックで，実装した．具体的には10日前以前でないとその値が現れないときに，RSSにレポートを入れるようにした．
<p>
例えば，1/17日のEURが117円/EURだとすると，EURの117円というのは最近2ヶ月以上無いため，こういうRSSになる．
</p>
<div>
<pre>
&lt;title&gt;[為替] (EUR) 2009-01-17 120.45 (LOW 0/2/20)&lt;/title&gt;
&lt;description&gt;ユーロ(EUR) の為替レート:117.00．2ヶ月20日ぶりの安値です．前回は，2008/10/28 の 116.15 円/EUR です．最安値は，2000/10/27 の 89.45 円/EUR です&lt;/description&gt;
</pre>
</div>
&lt;title&gt;と&lt;description&gt;属性にレポートを入れて，2ヶ月20日ぶりの安値だということがわかるようにした．(高値の場合は逆に「LOW」が「HIGH」になる)
<p>
これで，かなりレート変化の雰囲気をRSSから読み取りやすくなったと思う．
</p>]]></content:encoded>
    <dc:date>2009-01-18T00:48:05+09:00</dc:date>
    <dc:subject>RSS</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?RSS%A4%C7%C1%B4%CA%B8%C7%DB%BF%AE%A4%B9%A4%EB">
    <title>RSSで全文配信する</title>
    <link>http://kamoland.com/wiki/wiki.cgi?RSS%A4%C7%C1%B4%CA%B8%C7%DB%BF%AE%A4%B9%A4%EB</link>
    <description>カモランドで提供しているRSSを，記事全文を載せるように変更した．Yuki::RSS.pmを改造して，contentモジュールの表記で生成するようにした．</description>
    <content:encoded><![CDATA[<p>
カモランドで提供しているRSSを，記事全文を載せるように変更した．Yuki::RSS.pmを改造して，contentモジュールの表記で生成するようにした．

</p>

<h2><a name="i0"> </a>RSSで全文配信する</h2>
<div></div><h3><a name="i1"> </a>はじめに</h3>
<a title="RSSについて" href="http://kamoland.com/wiki/wiki.cgi?RSS%A4%CB%A4%C4%A4%A4%A4%C6">カモランドでのRSSの提供</a>だが，当初は通信頻度の多さを考えて，<a title="カモランドのRSS対応" href="http://kamoland.com/wiki/wiki.cgi?%A5%AB%A5%E2%A5%E9%A5%F3%A5%C9%A4%CERSS%C2%D0%B1%FE">サマリだけを配信すべき</a>だと考えていたのだが，
自分のRSS利用生活が進んでいくと，利用者としてはRSSとして全文を配信してもらったほうが，
RSSリーダー上で読み取りが完結するので便利だと考えるようになった．
<p>
俺のRSS利用生活は，
</p>
<ol>
<li><a href="http://www.bloglines.com/">Bloglines</a> にRSSフィードを登録し，BloglinesのクローラにRSSの中身を収集してもらう</li>
<li>収集された結果をBloglinesから<a title="Bloglinesの記事をメールとして受け取る" href="http://kamoland.com/wiki/wiki.cgi?Bloglines%A4%CE%B5%AD%BB%F6%A4%F2%A5%E1%A1%BC%A5%EB%A4%C8%A4%B7%A4%C6%BC%F5%A4%B1%BC%E8%A4%EB">APIで取得</a>して，自作リーダーで閲覧する</li>
</ol>
<p>
という感じなのだが，全文を配信していないフィード
(<a href="http://it.nikkei.co.jp/">NIKKEI NET - IT PLUS</a>，
<a href="http://www.oracle.com/technology/global/jp/index.html">OTN Japanの掲示板</a>，
<a href="http://www.atmarkit.co.jp/">＠IT</a>，
<a href="http://jvn.jp/">JVN</a> など)
への対応として，
全文を取得して表示するような実装を自作リーダーにわざわざ作りこんでいる．
理由は，記事本体のページに飛ぶのが面倒で，時間のロスだからだ．
RSSリーダー上で，記事本体も読めるようにしてしまっている．
</p>
<p>
しかしサイトによって全文取得の方法が違っているので実装を分けているのが面倒だし，今後のメンテ上もいまいちだ．
(実装とは具体的には，取得したページのHTMLからページヘッダ，ナビゲーション部などを除去して記事本文を切り出すところ．
これはサイトのページデザインにもろに依存する)
</p>
<p>
最近のスラドにもこういう話題が出ており，全文配信が便利だと感じている人は俺だけではないみたいだ．
</p>
<ul>
<li><a href="http://slashdot.jp/it/article.pl?sid=08/11/25/1230233">スラッシュドット・ジャパン | RSS フィードの妥当な内容量はどれ位？</a></li>
</ul>
<p>
．．．全文配信で便利になるなら，配信しようではないか．
</p>

<div></div><h3><a name="i2"> </a>RSSに全文を載せる方法</h3>
技術的にはどうなのかだが(
<a href="http://www.kanzaki.com/docs/sw/rss.html">RSS -- サイト情報の要約と公開 The Web KANZAKI</a>
)，RSSからはcontentモジュールを使った表記で全文配信できるようだ．
(これまでサマリを入れていた&lt;description&gt;に全文を入れてしまうのは，さすがに気が引けるのでやらない)
<p>
また，この利用法が一般的に通用するのか，世の中のRSSリーダーが解釈してくれるのかが気になるが，
いくつか調べたところ，<a href="http://blog.fc2.com/">FC2ブログ</a> のRSSがこの形式(contentモジュールによる全文配信)をとっていたので，
FC2ブログがやってるならまぁ大丈夫なんじゃなかろうかという気になった．
実際<a href="http://www.bloglines.com/">Bloglines</a> では，FC2ブログの記事全文を正しく表示できていた．
</p>
<p>
しかし&lt;content:encoded&gt;を使うとしても，単純に記事全文をCDATAで入れれば良いというものではなかった．
実際のカモランドの記事HTMLをチェックしてみると，ここらへんがまずそう．
</p>
<dl>
<dt>JavaScript</dt>
<dd>WebインタフェイスのRSSリーダーだと誤って動作してしまう可能性があるので，除去する必要がある</dd>
<dt>スタイルシート</dt>
<dd>リーダー側でどうなるか不明なので，一応除去する</dd>
<dt>相対パス形式のリンク</dt>
<dd>絶対パスにする必要がある</dd>
</dl>
<p>
配信サイズもできれば節約したいので，結局HTMLタグについては，基本的な文書構造に関して出力しうる必要最小限を
残して，それ以外は除去するようにした．
</p>
<p>
つまり，同じ記事に対して，
</p>
<div>
<pre>
HTML形式(記事本体)
 → [JavaScript等の除去] → RSSに入れる全文HTML形式(content:encoded)
 → [サマリ抽出] → RSSに入れるサマリの形式(description)
</pre>
</div>
の3種類を生成することになる．

<div></div><h4><a name="i3"> </a>Yuki::RSS.pmの改造</h4>
うちではRSSの生成にYuki::RSS.pmを使っているが，これをcontentに対応するために改造した．
<p>
要は，
</p>
<ul>
<li>contentモジュール用のネームスペースxmlns:contentを定義する</li>
<li>各itemに&lt;content:encoded&gt;要素を出力する</li>
<li>&lt;content:encoded&gt;要素向けのHTML変換を行う</li>
</ul>
<p>
という感じ．
</p>
<p>
<span>RSS.pmのas_string関数</span>
</p>
<div>
<pre>
sub as_string {
    my ($self) = @_;
    my $doc = &lt;&lt;"EOD";
&lt;?xml version="1.0" encoding="$self-&gt;{encoding}" ?&gt;

&lt;rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/" 
>

&lt;channel rdf:about="$self-&gt;{channel}-&gt;{link}"&gt;
 &lt;title&gt;$self-&gt;{channel}-&gt;{title}&lt;/title&gt;
 &lt;link&gt;$self-&gt;{channel}-&gt;{link}&lt;/link&gt;
 &lt;description&gt;$self-&gt;{channel}-&gt;{description}&lt;/description&gt;
 &lt;items&gt;
  &lt;rdf:Seq&gt;
   @{[
    map {
     qq{&lt;rdf:li rdf:resource="$_-&gt;{link}" /&gt;}
    } @{$self->{items}}
   ]}
  &lt;/rdf:Seq&gt;
 &lt;/items&gt;
&lt;/channel&gt;
@{[
 map {
  qq{
   &lt;item rdf:about="$_-&gt;{link}"&gt;
    &lt;title&gt;$_-&gt;{title}&lt;/title&gt;
    &lt;link&gt;$_-&gt;{link}&lt;/link&gt;
    &lt;description&gt;$_-&gt;{description}&lt;/description&gt;
    &lt;content:encoded&gt;&lt;![CDATA[@{[ filter_content($_-&gt;{content}) ]}]]&gt;&lt;/content:encoded&gt; 
    &lt;dc:date&gt;$_-&gt;{dc_date}&lt;/dc:date&gt;
    &lt;dc:subject&gt;$_-&gt;{subject}&lt;/dc:subject&gt;
   &lt;/item&gt;
  }
 } @{$self->{items}}
]}
&lt;/rdf:RDF&gt;
EOD
}
</pre>
</div>
<p>
<span>RSS.pmに追加した関数</span>
</p>
<div>
<pre>
# HTMLを&lt;content:encoded&gt;向けの内容に変換する
# これはカモランドのWikiが生成するHTMLに合わせた変換なので，
# 実際にサイトで使っているHTMLタグに合わせて変換をカスタマイズする必要あり
#
sub filter_content {
	my ($c) = @_;

	$c =~ s/&lt;script.+?&lt;\/script.*?&gt;//gis;
	$c =~ s/&lt;style.+?&lt;\/style.*?&gt;//gis;
	$c =~ s/&lt;([^&gt;]+)&gt;/tagfilter($1)/eg;

	return $c;
}

sub tagfilter {
	my ($tag) = @_;

	$tag = tagfilter2($tag);
	$tag =~ s/ class="[^"]+"//;
	$tag =~ s/ class='[^']+'//;
	return $tag;
}

sub tagfilter2 {
	my ($tag) = @_;
	my $ltag = lc $tag;

	return "&lt;$tag&gt;" if ($ltag =~ /^\/?p$/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?h[0-9]$/);
	return "&lt;$tag&gt;" if ($ltag =~ /^a /);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/a$/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?li( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?ul( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?ol( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?pre( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?br$/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?span( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?div( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?table( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?tr( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?td( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?th( |$)/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?dl$/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?dt$/);
	return "&lt;$tag&gt;" if ($ltag =~ /^\/?dd$/);
}
</pre>
</div>]]></content:encoded>
    <dc:date>2008-12-06T13:39:42+09:00</dc:date>
    <dc:subject>RSS</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?RSS%A4%CB%A4%C4%A4%A4%A4%C6">
    <title>RSSについて</title>
    <link>http://kamoland.com/wiki/wiki.cgi?RSS%A4%CB%A4%C4%A4%A4%A4%C6</link>
    <description>KamoLandでは，カモランドの新着記事の情報や，カモランドで収集した為替レートの情報などを， RSSフォーマットで提供しています．</description>
    <content:encoded><![CDATA[<p>
KamoLandでは，カモランドの新着記事の情報や，カモランドで収集した為替レートの情報などを， RSSフォーマットで提供しています．

</p>
<h2><a name="i0"> </a>RSSについて</h2>
カモランドでは，新着記事のタイトルやサマリなどの情報を， RSSフォーマットで提供しています．(RSS 1.0)
<div></div><h3><a name="i1"> </a>RSSフィード</h3>
<div></div><h4><a name="i2"> </a>KamoLand</h4>
<table cellspacing="1" border="1">
<tr><th>対象</th><th>RSSのURL</th></tr>
<tr><td>カモランド全体</td><td><a href="http://kamoland.com/rss/kamoland.xml">http://kamoland.com/rss/kamoland.xml</a></td></tr>
<tr><td>　自宅サーバの構築と運用</td><td><a href="http://kamoland.com/rss/homeserver.xml">http://kamoland.com/rss/homeserver.xml</a></td></tr>
<tr><td>　自宅サーバ以外の雑談(時事，ゲーム，音楽)</td><td><a href="http://kamoland.com/rss/zatudan.xml">http://kamoland.com/rss/zatudan.xml</a></td></tr>
<tr><td>　プログラマー's ペイジ(プログラミング，DB関連)</td><td><a href="http://kamoland.com/rss/programmer.xml">http://kamoland.com/rss/programmer.xml</a></td></tr>
<tr><td>　風景写真集</td><td><a href="http://kamoland.com/rss/landscape.xml">http://kamoland.com/rss/landscape.xml</a></td></tr>
</table>

<div></div><h4><a name="i3"> </a>RensaInfo</h4>
<table cellspacing="1" border="1">
<tr><th>対象</th><th>RSSのURL</th></tr>
<tr><td>RensaInfo全体 (入室ログ以外)</td><td><a href="http://www.rensa.info/rss/rensainfo.xml">http://www.rensa.info/rss/rensainfo.xml</a></td></tr>
<tr><td>　連鎖ゲームハイスコア(甘口)</td><td><a href="http://www.rensa.info/rss/rensagames1.xml">http://www.rensa.info/rss/rensagames1.xml</a></td></tr>
<tr><td>　連鎖ゲームハイスコア(中辛)</td><td><a href="http://www.rensa.info/rss/rensagames2.xml">http://www.rensa.info/rss/rensagames2.xml</a></td></tr>
<tr><td>　連鎖ゲームハイスコア(辛口)</td><td><a href="http://www.rensa.info/rss/rensagames3.xml">http://www.rensa.info/rss/rensagames3.xml</a></td></tr>
<tr><td>　連鎖ゲームハイスコア(激辛)</td><td><a href="http://www.rensa.info/rss/rensagames4.xml">http://www.rensa.info/rss/rensagames4.xml</a></td></tr>
<tr><td>　連鎖ゲームハイスコア(COM大会)</td><td><a href="http://www.rensa.info/rss/rensagames5.xml">http://www.rensa.info/rss/rensagames5.xml</a></td></tr>
<tr><td>　連鎖ウィキ</td><td><a href="http://www.rensa.info/rss/wiki.xml">http://www.rensa.info/rss/wiki.xml</a></td></tr>
<tr><td>連鎖ゲーム対戦部屋の入室ログ</td><td><a href="http://www.rensa.info/rss/roomlog.xml">http://www.rensa.info/rss/roomlog.xml</a></td></tr>
</table>
<p>
RSSリーダーを使用することで，カモランドをブラウザで開くことなく更新情報の確認を行うことができます．
</p>
<p>
RSSの更新は30分毎に行いますので，RSSリーダーはそれより長い更新間隔に設定して使用することをお勧めします．
</p>
<div></div><h4><a name="i4"> </a>為替レート</h4>
<table cellspacing="1" border="1">
<tr><th>対象</th><th>RSSのURL</th></tr>
<tr><td>為替レート(CAD,GBP,USD,AUD,EUR,NZD)</td><td><a href="http://kamoland.com/rss/kawase_test.xml">http://kamoland.com/rss/kawase_test.xml</a></td></tr>
</table>
<p>
citibankのサイトから取得した為替レートを，RSS化しています．1日1回昼頃に更新します．
詳しくは，<a title="為替レートのRSSを生成する" href="http://kamoland.com/wiki/wiki.cgi?%B0%D9%C2%D8%A5%EC%A1%BC%A5%C8%A4%CERSS%A4%F2%C0%B8%C0%AE%A4%B9%A4%EB">為替レートのRSSを生成する</a>を参照．
また，ブログパーツ風に使える<a title="為替チャートをブログパーツ風にする" href="http://kamoland.com/wiki/wiki.cgi?%B0%D9%C2%D8%A5%C1%A5%E3%A1%BC%A5%C8%A4%F2%A5%D6%A5%ED%A5%B0%A5%D1%A1%BC%A5%C4%C9%F7%A4%CB%A4%B9%A4%EB">チャートのグラフ</a>も提供しています．
</p>
<p>
また，twitterでもbot(ボット)がつぶやいています．<a href="http://twitter.com/kawaseneko">@kawaseneko</a> お気軽にフォローしてみてください
</p>
<div></div><h3><a name="i5"> </a>OPML</h3>
カモランドの全てのRSSフィードを収録したOPMLは，以下のファイルです．

<table cellspacing="1" border="1">
<tr><th>範囲</th><th>URL</th></tr>
<tr><td>全てのRSSフィード</td><td><a href="http://kamoland.com/kamoland.opml">http://kamoland.com/kamoland.opml</a></td></tr>
</table>
<p>
OPMLに対応したリーダの場合，これを使えば一気に登録を行えて便利です．
</p>]]></content:encoded>
    <dc:date>2008-11-24T13:32:58+09:00</dc:date>
    <dc:subject>RSS</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?META%A5%BF%A5%B0%A4%CF%CC%B5%B0%D5%CC%A3%A4%C7%A4%CF%A4%CA%A4%A4%A4%E8%A4%A6%A4%C0">
    <title>METAタグは無意味ではないようだ</title>
    <link>http://kamoland.com/wiki/wiki.cgi?META%A5%BF%A5%B0%A4%CF%CC%B5%B0%D5%CC%A3%A4%C7%A4%CF%A4%CA%A4%A4%A4%E8%A4%A6%A4%C0</link>
    <description>METAタグのdescriptionは，SEO的にはもはや過去の遺物だと思っていたが，YahooとGoogleの説明によるとそういうわけでもないようだ．</description>
    <content:encoded><![CDATA[<p>
METAタグのdescriptionは，SEO的にはもはや過去の遺物だと思っていたが，YahooとGoogleの説明によるとそういうわけでもないようだ．
</p>
<p>

<a href="http://searchblog.yahoo.co.jp/2008/09/yahoo_72.html">Yahoo!検索インフォセンターというのができたらしい</a> ので，
フンフ〜ンという感じで眺めてみた．
</p>
<p>
すると，
</p>
<ul>
<li><a href="http://info.search.yahoo.co.jp/archives/002838.php">Yahoo!検索コンテンツ品質ガイドライン</a></li>
</ul>
<p>
として，何と以下の記述があった．
</p>
<div>
<pre>
Yahoo! JAPANが検索結果に表示されるように努めているのは次のようなウェブページです。
 ・・・
タイトルやディスクリプションなどのメタデータ（HTMLの&lt;head&gt;のなかの記述）で、
ウェブページの内容が適切に記述されているウェブページ。
</pre>
</div>
ディスクリプションを見ているのか？
<p>
METAタグのdescriptionは，一昔前にあったスパムサイトの関係でもはや全然使われていないものだと思っていたのだが，
そういうわけではないのか．
</p>
<p>
Googleについても調べてみたが，Googleも使っているようだ．しかも状況によっては検索結果のスニペットに出すと言っている．
</p>
<ul>
<li><a href="http://www.google.com/support/webmasters/bin/answer.py?answer=35264">検索結果でサイトのタイトルと説明を変更する</a></li>
</ul>
<p>
カモランドでは，METAタグのdescriptionは過去の一時期は使っていたが，今はやめてしまっている．
</p>
<p>
しかしこういう話なら，復活させてみようかのう．
</p>]]></content:encoded>
    <dc:date>2008-09-18T21:35:01+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%B2%F2%C0%CF%A4%F2DB%A4%C7%A4%E4%A4%EB">
    <title>Apacheのログ解析をDBでやる</title>
    <link>http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%B2%F2%C0%CF%A4%F2DB%A4%C7%A4%E4%A4%EB</link>
    <description>前回書いたように，Google Analyticsから足を洗った．そのため，アクセスログを自前で解析しなければならない．そこで，ApacheのアクセスログをDB(PostgreSQL)に入れて解析することにした．</description>
    <content:encoded><![CDATA[<p>
<a title="GoogleAdsenseなどをやめた理由" href="http://kamoland.com/wiki/wiki.cgi?GoogleAdsense%A4%CA%A4%C9%A4%F2%A4%E4%A4%E1%A4%BF%CD%FD%CD%B3">前回</a>書いたように，Google Analyticsから足を洗った．そのため，アクセスログを自前で解析しなければならない．そこで，ApacheのアクセスログをDB(PostgreSQL)に入れて解析することにした．

</p>
<p>
昔は<a href="http://www.analog.cx/">Analog</a>を使っていて，それでも機能的には特に不満はなかったのだが，DBに入れてしまえばSQLで色々遊べそうなのが良い．ＳＱＬ！ ＳＱＬ！
</p>
<p>
．．．というわけでやってみたので，<a title="ApacheのログをDBで解析する" href="http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%A4%F2DB%A4%C7%B2%F2%C0%CF%A4%B9%A4%EB">ApacheのログをDBで解析する</a>に書いた．
</p>
<p>
人の参考になるかどうかは判らん内容だが，一応Apacheログテーブルの主キーは工夫したつもりだ．
これ，安易にシーケンスを主キーにしたりすると，access_logからDBに登録する運用が結構面倒になるはず．リクエストのDB重複登録を防ぐことを考えると．
</p>
<p>
あと課題としては，
</p>
<ul>
<li>検索単語レポート</li>
</ul>
<p>
をSQLでどうやって作るか，がある．
</p>
<p>
検索単語レポートとは，うちのページに遷移してくる前に検索エンジンで使われた検索語をリファラーから拾って，それを集計するというものだが，
URLエンコード済みの文字列から全角文字の検索語をデコードするのは単純ではない．
</p>
<p>
<a title="キーワード抽出による関連ページ導出(2)" href="http://kamoland.com/wiki/wiki.cgi?%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%C3%EA%BD%D0%A4%CB%A4%E8%A4%EB%B4%D8%CF%A2%A5%DA%A1%BC%A5%B8%C6%B3%BD%D0%282%29">キーワード抽出による関連ページ導出(2)</a>に書いたとおり，リファラーのURLに含まれるパラメータを検索エンジン別に判断して，使われているエンコーディング(UTF-8/Shift-JIS/EUC-JP)を求める必要がある．
</p>
<p>
ここは，PL/pgSQLでFunctionを作るのだろうか．う〜む
</p>]]></content:encoded>
    <dc:date>2008-08-24T00:40:23+09:00</dc:date>
    <dc:subject>サイトマスターの雑感</dc:subject>
    
   </item>
   
   <item rdf:about="http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%A4%F2DB%A4%C7%B2%F2%C0%CF%A4%B9%A4%EB">
    <title>ApacheのログをDBで解析する</title>
    <link>http://kamoland.com/wiki/wiki.cgi?Apache%A4%CE%A5%ED%A5%B0%A4%F2DB%A4%C7%B2%F2%C0%CF%A4%B9%A4%EB</link>
    <description>色々統計を取るにはDBの方が便利なので，ApacheのアクセスログをDBに格納することにした．DBはPostgreSQL 8.3を使う．</description>
    <content:encoded><![CDATA[<p>
色々統計を取るにはDBの方が便利なので，ApacheのアクセスログをDBに格納することにした．DBはPostgreSQL 8.3を使う．

</p>

<h3><a name="i0"> </a>DBの定義</h3>
以下のテーブルを作成した．
<table cellspacing="1" border="1">
<tr><th>テーブルNo</th><th>テーブル名(論理)</th><th>テーブル名(物理)</th></tr>
<tr><td>1</td><td>Apacheログテーブル</td><td>apache_log</td></tr>
<tr><td>2</td><td>除外ユーザーエージェントテーブル</td><td>al_useragent_ex</td></tr>
</table>


<div></div><h4><a name="i1"> </a>１．Apacheログテーブル</h4>
アクセスログを格納するテーブルは，以下の定義で作成した．
基本的にはcombined形式ログに含まれる項目を列挙したものだが，最後の2カラムを追加している．あ，vhostも違うか．
<p>
<span>Apacheログテーブル</span>
物理名：apache_log
</p>
<table cellspacing="1" border="1">
<tr><th>列No.</th><th>列名(論理)</th><th>列名(物理)</th><th>データ型</th><th>必須</th><th>主キー</th></tr>
<tr><td>1</td><td>VirtualHost名</td><td>vhost</td><td>text</td><td>Yes</td><td>1</td></tr>
<tr><td>2</td><td>リモートホスト</td><td>hostname</td><td>text</td><td>Yes</td><td>　</td></tr>
<tr><td>3</td><td>identユーザ</td><td>identuser</td><td>text</td><td>　</td><td>　</td></tr>
<tr><td>4</td><td>basic認証ユーザ</td><td>basicuser</td><td>text</td><td>　</td><td>　</td></tr>
<tr><td>5</td><td>リクエスト日時</td><td>reqtime</td><td>timestamp</td><td>Yes</td><td>2</td></tr>
<tr><td>6</td><td>HTTPメソッド</td><td>method</td><td>text</td><td>Yes</td><td>　</td></tr>
<tr><td>7</td><td>リクエストターゲット</td><td>target</td><td>text</td><td>Yes</td><td>　</td></tr>
<tr><td>8</td><td>プロトコル</td><td>proto</td><td>text</td><td>Yes</td><td>　</td></tr>
<tr><td>9</td><td>レスポンスコード</td><td>statuscode</td><td>text</td><td>Yes</td><td>　</td></tr>
<tr><td>10</td><td>レスポンスバイト数</td><td>bytes</td><td>integer</td><td>　</td><td>　</td></tr>
<tr><td>11</td><td>リファラー</td><td>referer</td><td>text</td><td>　</td><td>　</td></tr>
<tr><td>12</td><td>ユーザーエージェント</td><td>useragent</td><td>text</td><td>Yes</td><td>　</td></tr>
<tr><td>13</td><td>アクセスログ行番号</td><td>loglineno</td><td>integer</td><td>Yes</td><td>3</td></tr>
<tr><td>14</td><td>登録日時</td><td>reg_date</td><td>timestamp</td><td>Yes</td><td>　</td></tr>
</table>
<p>
アクセスログ行番号は，アクセスログファイル(access_logとか)内での行番号．
これを主キーに組み込むことで，DB登録の時に同じアクセスログファイルを繰り返し使っても，
リクエストがDBに重複登録されないようにしている．
</p>
<p>
データのロードは，Perlのプログラムで行った．access_logのファイルを読んで，
DBI経由でApacheログテーブルにINSERTした．
</p>

<div></div><h4><a name="i2"> </a>２．除外ユーザーエージェントテーブル</h4>
検索エンジンなどのロボットからのアクセスは，統計を取るときに除外することが多い．
ページに人気があるかどうかを調べる上で，ロボットからのアクセス数は意味がないからだ．
(もっとも，これは統計を取る観点によりけりです)
<p>
そこで，その除外処理に必要な情報もテーブルに登録しておく．
</p>
<p>
<span>除外ユーザーエージェントテーブル</span>
物理名：al_useragent_ex
</p>
<table cellspacing="1" border="1">
<tr><th>列No.</th><th>列名(論理)</th><th>列名(物理)</th><th>データ型</th><th>必須</th><th>主キー</th></tr>
<tr><td>1</td><td>除外パターン</td><td>ex_pattern</td><td>text</td><td>Yes</td><td>1</td></tr>
<tr><td>2</td><td>登録日時</td><td>reg_date</td><td>timestamp</td><td>Yes</td><td>　</td></tr>
</table>
<p>
除外するユーザーエージェントを，SQLのLIKE書式でex_patternに登録する．
</p>
<p>
<span>除外ユーザーエージェントテーブルの内容</span>
</p>
<table cellspacing="1" border="1">
<tr><th>ex_pattern</th></tr>
<tr><td>%Google%</td></tr>
<tr><td>Infoseek%</td></tr>
<tr><td>Scooter%</td></tr>
<tr><td>Ultraseek%</td></tr>
<tr><td>ia_archiver%</td></tr>
<tr><td>moget%</td></tr>
<tr><td>gazz%</td></tr>
<tr><td>Bookmark%</td></tr>
<tr><td>Aruyo%</td></tr>
<tr><td>Wget%</td></tr>
<tr><td>libwww-perl%</td></tr>
<tr><td>WebAuto%</td></tr>
<tr><td>dloader%</td></tr>
<tr><td>msnbot%</td></tr>
<tr><td>Feedfetcher%</td></tr>
<tr><td>Feedpath%</td></tr>
<tr><td>Bloglines%</td></tr>
<tr><td>RssReader%</td></tr>
<tr><td>RSS%</td></tr>
<tr><td>YahooFeedSeeker%</td></tr>
<tr><td>Agent%</td></tr>
<tr><td>PEAR%</td></tr>
<tr><td>Baiduspider%</td></tr>
<tr><td>Yeti%</td></tr>
<tr><td>%Slurp%</td></tr>
<tr><td>OOZBOT%</td></tr>
<tr><td>CyberPatrol SiteCat Webbot%</td></tr>
<tr><td>%Crawler%</td></tr>
<tr><td>%crawler%</td></tr>
<tr><td>%Bot%</td></tr>
<tr><td>psbot%</td></tr>
<tr><td>MaSagool%</td></tr>
</table>
<p>
この内容は，これからもログを適宜調べて増やしていく必要があるので面倒．．．
</p>

<div></div><h3><a name="i3"> </a>統計を取得する例</h3>
このテーブルを使って，今月の日別リクエスト数の統計を求める例．
<p>
<span>今月の日別リクエスト</span>
</p>
<div>
<pre>
・SQL
SELECT
	date_trunc('day', reqtime) AS d,
	count(*) AS nreq
FROM
	apache_log
WHERE
	vhost = 'kamoland.com' AND
	reqtime >= date_trunc('month', current_timestamp) AND
	reqtime &lt; date_trunc('month', current_timestamp) + interval '1 month'
	AND
	statuscode IN ('200', '206', '304')
	AND
	NOT EXISTS (
		SELECT 1 FROM al_useragent_ex WHERE useragent LIKE ex_pattern
	)
GROUP BY d
ORDER BY d

・実行結果
          d          | nreq
---------------------+-------
 2008-08-01 00:00:00 |  6374
 2008-08-02 00:00:00 |  3039
 2008-08-03 00:00:00 |  2761
 2008-08-04 00:00:00 |  6069
 2008-08-05 00:00:00 |  6401
 2008-08-06 00:00:00 |  7130
 2008-08-07 00:00:00 |  6732
 2008-08-08 00:00:00 |  6366
 2008-08-09 00:00:00 |  2432
 2008-08-10 00:00:00 |  3633
 2008-08-11 00:00:00 |  9177
 2008-08-12 00:00:00 | 14913
 2008-08-13 00:00:00 | 11264
 2008-08-14 00:00:00 |  6897
 2008-08-15 00:00:00 |  6998
 2008-08-16 00:00:00 |  4211
 2008-08-17 00:00:00 |  4082
 2008-08-18 00:00:00 |  9344
 2008-08-19 00:00:00 | 10803
 2008-08-20 00:00:00 |  8860
 2008-08-21 00:00:00 |  8383
 2008-08-22 00:00:00 |  8677
 2008-08-23 00:00:00 |   602
(23 rows)
</pre>
</div>
statuscodeの条件は，考える余地がある．俺の場合は，
<ul>
<li>リダイレクト(301,302)は，二重カウントになるので除外する</li>
<li>エラー(404や500など)は，カウントしない</li>
</ul>
<p>
という基本方針で，
</p>
<div>
<pre>
statuscode IN ('200', '206', '304')
</pre>
</div>
にしている．
<p>
あと実行計画は以下の通りで，まぁapache_logテーブルのSeqScanは回避しているので良かろう．
</p>
<p>
<span>実行計画</span>
</p>
<div>
<pre>
----- 実行計画 -----
Sort  (cost=1031579.43..1031579.94 rows=201 width=8) (actual time=11926.030..11926.088 rows=23 loops=1)
  Sort Key: (date_trunc('day'::text, apache_log.reqtime))
  Sort Method:  quicksort  Memory: 17kB
  ->  HashAggregate  (cost=1031568.73..1031571.74 rows=201 width=8)
 (actual time=11925.776..11925.860 rows=23 loops=1)
        ->  Bitmap Heap Scan on apache_log  (cost=8472.23..1031201.20 rows=73506 width=8)
 (actual time=815.828..11236.473 rows=155148 loops=1)
              Recheck Cond: ((vhost = 'kamoland.com'::text) AND (reqtime >= date_trunc('month'::text, now()))
 AND (reqtime &lt; (date_trunc('month'::text, now()) + '1 mon'::interval)))
              Filter: ((statuscode = ANY ('{200,206,304}'::text[])) AND (NOT (subplan)))
              ->  Bitmap Index Scan on apache_log_p  (cost=0.00..8453.85 rows=169990 width=0)
 (actual time=799.165..799.165 rows=242821 loops=1)
                    Index Cond: ((vhost = 'kamoland.com'::text) AND (reqtime >= date_trunc('month'::text, now()))
 AND (reqtime &lt; (date_trunc('month'::text, now()) + '1 mon'::interval)))
              SubPlan
                ->  Seq Scan on al_useragent_ex  (cost=0.00..24.50 rows=6 width=0)
 (actual time=0.029..0.029 rows=0 loops=231411)
                      Filter: ($0 ~~ ex_pattern)
Total runtime: 11926.463 ms
</pre>
</div>]]></content:encoded>
    <dc:date>2008-08-24T00:18:30+09:00</dc:date>
    <dc:subject>Apache</dc:subject>
    
   </item>
  
</rdf:RDF>
