他のサイトをページ内に表示する

 ここでは検索エンジンを利用するのではなく、指定したURLのサイトをページ内に表示させてみます。検索エンジンを利用する際には検索するキーワードをCGIに渡しましたが、キーワードではなくURLを渡すようにすれば任意のサイトのページデータを取得することができます。まず、CGI部分ですが、渡されたURLをcurlのパラメータとします。他は今までと同じです。
 スクリプトのソース部分は前項とほとんど同じです。(実際のサンプルを実行する

#!/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 '"+inputdata+"'")
while !fh.eof
str = fh.gets
print Kconv::toutf8(str)
end
fh.close

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>他のサイトをページ内に表示する</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 siteSearch()
{
srchStr = document.getElementById("query").value;
if (srchStr == "") return;
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET","curl.rb?query="+srchStr+"&cache="+(new Date()).getTime(),true);
$("progress").style.visibility = "visible";
$("query").disabled = true;
$("sendButton").disabled = true;
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
newWindow();
$("result"+ winNum).innerHTML = httpObj.responseText;
winNum++;
$("query").disabled = false;
$("sendButton").disabled = false;
}
}
function newWindow()
{
$("progress").style.visibility = "hidden";
var dObj = $("window0").cloneNode(true);
var winObj = $("contents").appendChild(dObj);
winObj.id = "window"+winNum;
winObj.childNodes[0].id = "result"+winNum;
addEvent("window"+winNum,"click",closeWindow,false);
addEvent("window"+winNum,"mousedown",activeWindowDrag,false);
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.window.push("window"+winNum);
dragObj.maxLayer = dragObj.window.length;
inactiveWindow();
activeWindow(winNum);
}
// ウィンドウをアクティブにする処理
function activeWindow(n)
{
$("window"+n).style.backgroundImage = "url(titlebar.gif)";
}
function activeWindowDrag(evt)
{
inactiveWindow();
var obj = getEventTarget(evt);
if (obj.id.indexOf("window") == -1) return;
obj.style.backgroundImage = "url(titlebar.gif)";
}
// ウィンドウを全てインアクティブにする処理
function inactiveWindow()
{
for (var i=0; i<winNum; i++)
{
try {
$("window"+i).style.backgroundImage = "url(titlebar2.gif)";
}catch(e){}
}
}
// ウィンドウを閉じる処理
function closeWindow(e)
{
// クローズボックス上でマウスボタンが押されたか?
if ((dragObj.offsetX < 2) || (dragObj.offsetX >14) || (dragObj.offsetY < 4) || (dragObj.offsetY > 16)) return;
wObj = getEventTarget(e);
contObj = $("contents");
// ウィンドウをノードから削除
for (var i=0; i<contObj.childNodes.length; i++)
{
if(contObj.childNodes[i].id == wObj.id) contObj.removeChild(contObj.childNodes[i]);
}
// ウィンドウリストから削除
var temp = new Array();
for (i=0; i<dragObj.window.length; i++)
{
if (dragObj.window[i] != wObj.id) temp.push(dragObj.window[i]);
}
dragObj.window = temp;
}
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>他のサイトをページ内に表示する</h1>
<form method="get" name="ajaxForm" onsubmit="siteSearch();return false;">
<input type="text" value="http://" id="query" size="80"><br>
<input type="button" value="指定URLのページを表示" onClick="siteSearch()" id="sendButton">
</form>
<div id="contents"></div>
<div id="window0" class="windowBorder"><div id="result0" class="windowContents"></div>
</div>
<div id="progress"><img src="ring.gif"> データを読み込み中です...</div>
</body>
</html>

 いろいろなページを表示させると、場合によってはURLが間違っていたりすると延々と読み込み状態になってしまったりすることがあります。もしくはレスポンス(反応)が悪くて、読み込みを中断したい場合があります。読み込みを中断するにはabort()メソッドを使います。XMLHttpRequest()で作成したオブジェクトに対してabort()を使えば現在行われている通信が中断されます。(実際のサンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>他のサイトをページ内に表示する</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 siteSearch()
{
srchStr = document.getElementById("query").value;
if (srchStr == "") return;
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET","curl.rb?query="+srchStr+"&cache="+(new Date()).getTime(),true);
$("progress").style.visibility = "visible";
$("query").disabled = true;
$("sendButton").disabled = true;
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
newWindow();
$("result"+ winNum).innerHTML = httpObj.responseText;
winNum++;
$("query").disabled = false;
$("sendButton").disabled = false;
$("progress").style.visibility = "hidden";
}
}
// 通信を中断する
function abortHttp()
{
if (httpObj)
{
httpObj.abort();
$("progress").style.visibility = "hidden";
$("query").disabled = false;
$("sendButton").disabled = false;
}
}
function newWindow()
{
$("progress").style.visibility = "hidden";
var dObj = $("window0").cloneNode(true);
var winObj = $("contents").appendChild(dObj);
winObj.id = "window"+winNum;
winObj.childNodes[0].id = "result"+winNum;
addEvent("window"+winNum,"click",closeWindow,false);
addEvent("window"+winNum,"mousedown",activeWindowDrag,false);
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.window.push("window"+winNum);
dragObj.maxLayer = dragObj.window.length;
inactiveWindow();
activeWindow(winNum);
}
// ウィンドウをアクティブにする処理
function activeWindow(n)
{
$("window"+n).style.backgroundImage = "url(titlebar.gif)";
}
function activeWindowDrag(evt)
{
inactiveWindow();
var obj = getEventTarget(evt);
if (obj.id.indexOf("window") == -1) return;
obj.style.backgroundImage = "url(titlebar.gif)";
}
// ウィンドウを全てインアクティブにする処理
function inactiveWindow()
{
for (var i=0; i<winNum; i++)
{
try {
$("window"+i).style.backgroundImage = "url(titlebar2.gif)";
}catch(e){}
}
}
// ウィンドウを閉じる処理
function closeWindow(e)
{
// クローズボックス上でマウスボタンが押されたか?
if ((dragObj.offsetX < 2) || (dragObj.offsetX >14) || (dragObj.offsetY < 4) || (dragObj.offsetY > 16)) return;
wObj = getEventTarget(e);
contObj = $("contents");
// ウィンドウをノードから削除
for (var i=0; i<contObj.childNodes.length; i++)
{
if(contObj.childNodes[i].id == wObj.id) contObj.removeChild(contObj.childNodes[i]);
}
// ウィンドウリストから削除
var temp = new Array();
for (i=0; i<dragObj.window.length; i++)
{
if (dragObj.window[i] != wObj.id) temp.push(dragObj.window[i]);
}
dragObj.window = temp;
}
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>他のサイトをページ内に表示する</h1>
<form method="get" name="ajaxForm" onsubmit="siteSearch();return false;">
<input type="text" value="http://" id="query" size="80"><br>
<input type="button" value="指定URLのページを表示" onClick="siteSearch()" id="sendButton">
<input type="button" value="読み込みを中断" onClick="abortHttp()" id="abortButton">
</form>
<div id="contents"></div>
<div id="window0" class="windowBorder"><div id="result0" class="windowContents"></div>
</div>
<div id="progress"><img src="ring.gif"> データを読み込み中です...</div>
</body>
</html>

 次に一定時間経過したら自動的に読み込みを中断するようにしてみます。一定時間経過したら処理を行うにはsetTimeout()を使います。一定時間経過したら、先ほど作成した中断処理を行う関数を呼び出します。ただし、正常に読み込めた場合には、設定したタイマーをclearTimeout()を使ってクリアします。実際のスクリプトは以下のようになります。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>他のサイトをページ内に表示する</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 siteSearch()
{
srchStr = document.getElementById("query").value;
if (srchStr == "") return;
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET","curl.rb?query="+srchStr+"&cache="+(new Date()).getTime(),true);
$("progress").style.visibility = "visible";
$("query").disabled = true;
$("sendButton").disabled = true;
timerID = setTimeout("abortHttp()",30*1000); // 30秒でタイムアウト
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
clearTimeout(timerID); // タイマーをクリア
newWindow();
$("result"+ winNum).innerHTML = httpObj.responseText;
winNum++;
$("query").disabled = false;
$("sendButton").disabled = false;
$("progress").style.visibility = "hidden";
}
}
// 通信を中断する
function abortHttp()
{
if (httpObj)
{
httpObj.abort();
$("progress").style.visibility = "hidden";
$("query").disabled = false;
$("sendButton").disabled = false;
}
}
function newWindow()
{
$("progress").style.visibility = "hidden";
var dObj = $("window0").cloneNode(true);
var winObj = $("contents").appendChild(dObj);
winObj.id = "window"+winNum;
winObj.childNodes[0].id = "result"+winNum;
addEvent("window"+winNum,"click",closeWindow,false);
addEvent("window"+winNum,"mousedown",activeWindowDrag,false);
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.window.push("window"+winNum);
dragObj.maxLayer = dragObj.window.length;
inactiveWindow();
activeWindow(winNum);
}
// ウィンドウをアクティブにする処理
function activeWindow(n)
{
$("window"+n).style.backgroundImage = "url(titlebar.gif)";
}
function activeWindowDrag(evt)
{
inactiveWindow();
var obj = getEventTarget(evt);
if (obj.id.indexOf("window") == -1) return;
obj.style.backgroundImage = "url(titlebar.gif)";
}
// ウィンドウを全てインアクティブにする処理
function inactiveWindow()
{
for (var i=0; i<winNum; i++)
{
try {
$("window"+i).style.backgroundImage = "url(titlebar2.gif)";
}catch(e){}
}
}
// ウィンドウを閉じる処理
function closeWindow(e)
{
// クローズボックス上でマウスボタンが押されたか?
if ((dragObj.offsetX < 2) || (dragObj.offsetX >14) || (dragObj.offsetY < 4) || (dragObj.offsetY > 16)) return;
wObj = getEventTarget(e);
contObj = $("contents");
// ウィンドウをノードから削除
for (var i=0; i<contObj.childNodes.length; i++)
{
if(contObj.childNodes[i].id == wObj.id) contObj.removeChild(contObj.childNodes[i]);
}
// ウィンドウリストから削除
var temp = new Array();
for (i=0; i<dragObj.window.length; i++)
{
if (dragObj.window[i] != wObj.id) temp.push(dragObj.window[i]);
}
dragObj.window = temp;
}
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>他のサイトをページ内に表示する</h1>
<p>30秒でタイムアウトになります</p>
<form method="get" name="ajaxForm" onsubmit="siteSearch();return false;">
<input type="text" value="http://" id="query" size="80"><br>
<input type="button" value="指定URLのページを表示" onClick="siteSearch()" id="sendButton">
<input type="button" value="読み込みを中断" onClick="abortHttp()" id="abortButton">
</form>
<div id="contents"></div>
<div id="window0" class="windowBorder"><div id="result0" class="windowContents"></div>
</div>
<div id="progress"><img src="ring.gif"> データを読み込み中です...</div>
</body>
</html>

 次項ではページのデータではなくRSSで提供されているデータを利用して記事を検索してみます。

[第六章 6:RSSを利用して記事を検索するへ]
[目次へ]

(2006.1.22)