Yahoo検索結果を表示する

 ここではYahoo JAPANを利用して入力された検索語の検索結果をウィンドウ内に表示してみます。昨年(2005年)からはYahoo検索に関しては専用のAPIが用意されています。ここでは、APIを利用しない通常の検索方法で処理を行います。
 Yahoo JAPANで検索を行うとアドレス(URL)欄に

http://search.yahoo.co.jp/search?p=Ajax&fr=top&src=top&search.x=0&search.y=0

 のように表示されます。赤字で示す部分が検索文字列になります。
この検索文字列を連結してリクエストをYahoo JAPANに送信すれば検索結果を得る事ができます。結果は通常検索時に見られるHTMLデータになります。検索結果から何かを抽出することもできますが、そのような事を行う場合にはYahoo JAPANが用意している専用のAPIを利用する方がよいでしょう。
 AjaxではXMLHttpRequestで通信可能なのは同一サーバー内に限定されています。このため、Yahoo JAPANに対して上記のリクエストを送ることができません。そこで専用のCGIを用意し、1クッション入れてデータを受け取ることになります。サーバー側のプログラムは、慣れていないし、ほとんど作成した事がないので参考にならないかもしれませんが、以下のようになっています。

#!/usr/local/bin/ruby
require "kconv"
require "cgi-lib"
input = CGI.new
inputdata = input["query"]
bom = "\xef\xbb\xbf"
print "Content-type: text/html\n\n"
print bom
fh = open("| curl search.yahoo.co.jp/search?p="+inputdata)
while !fh.eof
str = fh.gets
print Kconv::toutf8(str)
end
fh.close

 Perlは分からないのでRuby 1.8.4を使って処理しています。やはりBOMを付けないとSafariで文字化けするため、UTF8に文字コードを変換してBOM付きで送り返すようにしています。
 クライアント側では以下のように入力フォームの検索文字列を読み出しサーバーに送信します。この時にURLがキャッシュされないようにするため送信時の時間をURLに付加します(これは、すでに説明済み。基本的にWindows 版 Internet Explorer対策)。検索結果はHTMLデータ=responseTextで受け取ることができます。あとは、divタグで設定された範囲内にinnerHTMLを使って表示します。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Yahoo検索結果を表示する</title>
<link rel="stylesheet" href="main.css" type="text/css" media="all">
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function yahooSearch()
{
srchStr = document.getElementById("query").value;
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET","curl.rb?query="+encodeURI(srchStr)+"&cache="+(new Date()).getTime(),true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = httpObj.responseText;
}
}
// --></script>
</head>
<body>
<h1>Yahoo検索結果を表示する</h1>
<form method="get" name="ajaxForm" onsubmit="yahooSearch();return false;">
<input type="text" value="" id="query">
<input type="button" value="Yahoo検索" onClick="yahooSearch()">
</form>
<div id="result">ここにYahoo検索結果が表示されます。</div>
</body>
</html>

 このスクリプトを実行するとブラウザによって若干動作が異なるのが分かります。特にFirefoxではYahoo JAPANのスタイルシートまで適用されてしまい、ページの見出し部分やフォームが崩れてしまっています。このように他のサイトのHTMLデータを表示する場合には注意が必要です。

 上記のようなスクリプトであれば別にAjaxを使わなくても通常のリンクとインラインフレームの組み合わせで実現できてしまいます。そこで、ややAjax的なものにしてみましょう。まず、ウィンドウを2枚用意し、検索された結果が交互に表示されるようにします。これら2枚のウィンドウはタイトルバーをつかんで自由にドラッグできるようにします。ドラッグ部分はすでに解説済みなので省略します。(実際のサンプルを実行する

 ただ、このスクリプトをMacOS X版のFirefox 1.5で実行すると以下のように前後関係が崩れて変なことになってしまいます(Firefox 2β1でも同様の現象が発生)。Windows版では発生しないのでMacOS X版のみのバグのようです。



 バグが解消されるのを期待して待つとして、もう少しAjaxっぽくしてみましょう。検索語が入力されたら新規にウィンドウを作成して、そこに結果が表示される方が、どちらかといえば一般的です。さきほどのスクリプトは、あらかじめウィンドウが2枚用意されていましたが、今回はひな形となるウィンドウを1枚用意し非表示にしておきます。非表示にするにはスタイルシートでvisibility:hiddenとしておきます(にも関わらずMacOS X版Firefox 1.5では画面が悲惨なことに)。
 今回はウィンドウを閉じるということは考えないので、とにかくウィンドウを作成するだけです。ウィンドウの作成はひな形のウィンドウをcloneNode()を使って複製します。複製したらスタイルシートでvisibility:visibileとして画面に表示します。このようにするとスクリプトでウィンドウの外観のパラメータなどを設定しなくてすみます。(実際のサンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Yahoo検索結果をマルチウィンドウで表示する</title>
<link rel="stylesheet" href="main.css" type="text/css" media="all">
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function yahooSearch()
{
srchStr = document.getElementById("query").value;
if (srchStr == "") return;
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET","curl.rb?query="+encodeURI(srchStr)+"&cache="+(new Date()).getTime(),true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
newWindow();
$("result"+ winNum).innerHTML = httpObj.responseText;
winNum++;
}
}
function newWindow()
{
var dObj = document.getElementById("window0").cloneNode(true);
var winObj = document.getElementById("contents").appendChild(dObj);
winObj.id = "window"+winNum;
winObj.childNodes[0].id = "result"+winNum;
addEvent("window"+winNum,"mousedown",dragObj.dragStart,false);
winObj.style.left = 10+Math.floor(Math.random()*400)+"px";
winObj.style.top = 150+Math.floor(Math.random()*200)+"px";
winObj.style.visibility ="visible";
winObj.style.zIndex = dragObj.zIndex + 1;
winObj.childNodes[0].style.visibility = "visible";
dragObj.maxLayer++;
dragObj.window.push("window"+winNum);
}
function initObj()
{
window.document.onmousemove = dragObj.dragProc;
window.document.onmouseup = dragObj.dragEnd;
winNum = 1;
dragObj.window = [];
dragObj.maxLayer = 1; // 最大レイヤー枚数
}
// --></script>
</head>
<body onload="initObj()" oncontextmenu="return false">
<h1>Yahoo検索結果をマルチウィンドウで表示する</h1>
<form method="get" name="ajaxForm" onsubmit="yahooSearch();return false;">
<input type="text" value="" id="query">
<input type="button" value="Yahoo検索" onClick="yahooSearch()">
</form>
<div id="contents"></div>
<div id="window0" class="windowBorder"><div id="result0" class="windowContents"></div>
</div>
</body>
</html>

 Internet Explorerでは問題ありませんが、FirefoxではYahooのスタイルが適用されてしまたり、Safari 2ではスクロールバーがドラッグできない(ホイールマウスではスクロールさせることができます)、MacOS X版Opera 8では全くスクロールさせることができない(ホイールマウスでも駄目)といった問題があります。多くのブラウザに対応させるためには、いろいろノウハウが必要なようです。

 あと、YahooでなくGoogleの検索結果を利用したい人がいるかもしれません。しかし、以下の規約にあるように自動的にクエリを送って結果を得るというのは駄目なようです。(Googleのサービス利用規約を読む。2006年7月現在では検索のAPIが公開されているので、いろいろな検索が可能です)
 ということで次項ではgoo検索を利用してみます。

[第六章 2:goo検索結果を表示するへ]
[目次へ]

(2006.1.18, 2006.9.2修正)