このページの本文へ

  • twitterでつぶやく
  • はてなブックマークに登録
  • del.icio.usに登録
  • livedoorクリップに登録
  • Buzzurlに登録
  • StumbleUponに登録
  • Google Bookmarksに登録
  • Facebookでシェア
  • Yahoo!ブックマークに登録
  • お気に入りに登録
  • 本文印刷

LPO導入で用語辞典からASCII.jpへの誘導が2倍に!

2008年11月28日 08時00分更新

文● 中野克平/デジタルコンテンツ部編成課/技術部基盤研究課


1.リファラーの取得と解析

 ユーザーがどのページから現在のWebページに到達したのかを取得するには、Webブラウザー内のJavaScriptプログラムでリファラーを取得してWebサーバーに伝える方法(「Ajax方式」と名付けよう)と、Webサーバー側でリファラー情報を取得する方法(「CGI方式」と名付けよう)がある。

 Ajax方式では、DOMを使ってWebページ内に動的に関連記事を埋め込めるので、静的HTMLのWebページでも実現できるメリットがある。だが、Webブラウザー側のJavaScriptプログラムとは別に、送信されたリファラーをWebサーバー側で受信する機能も必要であり、開発がやや面倒である。

 一方、CGI方式では、Webサーバーでリファラーを読み取る。PHPなど、サーバー側で動作するスクリプト言語を使えば、リファラーを取得して関連記事を表示する機能を、Webページのテンプレートなどに埋め込むだけ済むため、開発が容易である。しかし、Webページの生成ごとにリファラーを取得し、キーワードを解析して関連記事をデータベースで検索することになるから、Webサーバーの負担が重くなる。

 今回LPO機能を追加する用語辞典は、MediaWikiで動作している。MediaWikiはオンライン百科事典Wikipedia用のCMSで、Wikipediaも用語辞典も、負荷低減のためにMediaWikiとキャッシュサーバーを組み合わせて、処理の大半を省略している。用語辞典にLPOを付加するとき、CGI方式では動的に関連記事を生成する処理が新たに増え、しかもユーザーごとにページの内容が異なればキャッシュサーバーの出番が無くなる。Webページのうち、更新頻度の低い用語部分だけキャッシュする方法もあるが、今回はキャッシュサーバーの役割を変えずに済むAjax方式で開発することにした。

function getSearchString()
{
var g_pattern = /\?q=|&q=([^&]+)/;
var y_pattern = /p=([^&]+)/;
var ret = document.referrer.match(g_pattern);
if (ret) {
return ret[1];
}
ret = document.referrer.match(y_pattern)
if (ret){
return ret[1];
} 
return null;
} 
function serach(transport)
{
if ("" != transport.responseText) {
document.getElementById('articles').innerHTML =  transport.responseText;
document.getElementById('articles_header').innerHTML = S_HEADER + g_reqWords.replace(/\+/g,' ') + FOOTER;
} else {
req = 'q=' + encodeURIComponent(toXml(Array(decodeURIComponent(g_title)),Array()));
g_reqWords = decodeURIComponent(g_title);
myAjaxRequest(URL,req,midashi);
}
}
function myAjaxRequest(url,param,func)
{
new Ajax.Request(url, {
method:'get',
parameters: param,
onSuccess: func
}); 
}

Ajax方式で作ったLPOのJavaScriptプログラムの一部(全体はhttp://yougo.ascii.jp/articles/articles.jsでダウンロードできます)。「document.referrer」でWebブラウザーがWebサーバーに送信したリファラーを取得し、Googleなどの検索エンジンのリファラーであれば検索語を取り出してAjaxでサーバーに関連記事を問い合わせる仕組みです



2.関連記事のデータベース化

 検索語を含む関連記事を取得するには、ASCII.jpの記事を全文検索するためのデータベースが必要だ。しかしASCII.jpと用語辞典が動作するサーバーは別なので、ASCII.jpの最新記事を以下のようなXMLではき出すプログラムを用意し、用語辞典側サーバーで専用のデータベースに格納、検索できるようにした。

<CMSjpArticleAttributes>
<Build>Mon, 24 Nov 2008 15:03:16 +0900</Build>
<Version>1.0</Version>
<Site URL="http://ascii.jp/">ASCII.jp</Site>
<Articles>
<Article>
<EID>176173</EID>
<RegisterDate>Wed, 01 Oct 2008 01:44:52 +0900</RegisterDate>
<UpdateDate>Mon, 24 Nov 2008 02:43:54 +0900</UpdateDate>
<Editors>
<Editor ID="1004" Action="Register">廣田 稔</Editor>
<Editor ID="1004" Action="Update">廣田 稔</Editor>
</Editors>
<Categories>
<Category ID="13" Main="Yes">ネット</Category>
</Categories>
<Images>
<Image Class="Representative">
http://ascii.jp/elem/000/000/176/176201/000_90x90.jpg
</Image>
<Image Class="Thumbnail">
http://ascii.jp/elem/000/000/176/176201/000_40x40.jpg
</Image>
</Images>
<Attributes>
<Title>「こ、孔明の罠!」 ニコニコ動画(秋)の発表会に行ってきた</Title>
<SubTitle>気になる新機能を画像でチェック</SubTitle>
<Priority Level="0">通常</Priority>
<Restriction Level="-1">一般公開</Restriction>
<PublishBeginDate>Wed, 01 Oct 2008 09:44:12 +0900</PublishBeginDate>
<URL>http://ascii.jp/elem/000/000/176/176173/</URL>
<Summary>ドワンゴから、9月30日に新バージョンの発表会である「ニコニコ小会議」を開くという知らせが届いた。これはぜひ行かなければと会場に向かったところ……</Summary>
</Attributes>
<RelatedArticles>
<RelatedArticle>
<EID>148335</EID>
<Attributes>
<Title>「ひろゆき」のブロマイドを入手した</Title>
<URL>http://ascii.jp/elem/000/000/148/148335/</URL>
</Attributes>
</RelatedArticle>
<RelatedArticle>~略~</RelatedArticle>
</RelatedArticles>
</Article>
</Articles>
</CMSjpArticleAttributes>

将来的に記事配信のWeb APIを一般公開することも検討しており、XMLで記事情報を生成するプログラムを用意しました


3.関連記事の検索とHTML化

 用語辞典が利用しているデータベースサーバーはMySQL+Sennaで日本語の全文検索が可能であり、用語辞典LPOでは、以下のようなSQLで該当する記事を抽出している。

SELECT `Title`,`Url` FROM `article` WHERE MATCH (`Title`,`SubTitle`,`Summary`) AGAINST ('<検索語>' IN BOOLEAN MODE) LIMIT <検索上限>;


 こうして抽出した関連記事は、以下のようなPHPプログラムでHTMLとして出力している。

function printHtml($list)
{
print '<h2><span id="articles_header" class="mw-headline"></span></h2>';
print '<ul>';
foreach ( $list as $elem) {
print '<li><a href="' . $elem['Url'] . '" title="' . $elem['Title'] . '">' . $elem['Title'] . '</a></li>';
}
print '</ul>';
}

どうということのないPHPプログラムですが、さすがに毎秒数十~数百回のクエリーが実行されるとなると、サーバーの負荷が心配。MySQLとSennaの組み合わせは非常に高速な全文検索システムですが、用語辞典LPOではキャッシュサーバーにより、関連記事HTMLを一定時間キャッシュすることで、負荷を低減しています。


 キャッシュサーバーは、見出し語または検索語ごとに、関連記事のHTMLファイル(画面全体ではなく、関連記事部分のみ)を保持している。JavaScriptプログラムで、検索エンジン経由の場合は「検索語『○○○』の関連記事」、それ以外の場合は「見出し語『○○』の関連記事」と表示を切り替えている。

 なお、先ほど説明したとおり、用語辞典はMediaWikiを利用している。JavaScriptプログラムはMediaWikiの標準テンプレートであるmonobook.phpを改造して埋め込んだ。

用語辞典のLPO対策
「Windows」を検索エンジンで検索し、ASCII.jpデジタル用語辞典に来訪したユーザーには「検索語『Windows』の関連記事」と表示されます

次ページ:LPOでASCII.jpへの誘導を2倍に!

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く

みんなが買ってる最新アイテムはコレだ!

VOCALOID3 スターターIA ARIA ON THE PLANETES

VOCALOID3 スターターIA ARIA ON THE PLANETES

ヤマハ

17,745円〜

24人が購入

Google上位表示 64の法則 (WEB PROFESSIONAL)

Google上位表示 64の法則 (WEB PROFESSIONAL)

アスキー・メディアワークス

2,499円〜

72人が購入

標準HTML5タグリファレンス (WEB PROFESSIONAL)

標準HTML5タグリファレンス (WEB PROFESSIONAL)

アスキー・メディアワークス

2,205円〜

59人が購入

Speck MacBook Air 13型 See Thru - Clear SPK-MBA13-SEE-CLR

Speck MacBook Air 13型 See Thru - Clear SPK-MBA13-SEE-CLR

スペックコンピュータ

4,262円〜

23人が購入

jQuery Mobile スマートフォンサイト デザイン入門 (WEB PROFESSIONAL)

jQuery Mobile スマートフォンサイト デザイン入門 (WEB PROFESSIONAL)

アスキー・メディアワークス

2,499円〜

40人が購入

メモリーカード 32GB (PCH-Z321J)

メモリーカード 32GB (PCH-Z321J)

ソニー・コンピュータエンタテインメント

7,772円〜

9人が購入

iPhone 4S/4 防指紋性・高光沢機能性フィルム PRO GUARD AF for iPhone 4S/4 / PGAF-IPH4

iPhone 4S/4 防指紋性・高光沢機能性フィルム PRO GUARD AF for iPhone 4S/4 / PGAF-IPH4

マイクロソリューション Micro Solution Inc.

61人が購入

Amazon.co.jp