昨日は、月別にアーカイブされた記事のURLを取得するところまで書きましたので、今日はそのURLからHTMLを取得して検索を行う部分を書きます。
まず、以下のように月別のURLを格納している配列から順にHTMLを取得しています。
for(var i=0;i<cocosearch_archiveUrls.length;i++){
var url = archiveUrls[i];
new Ajax.Request(url, {method:'GET',onComplete:entryPageLoaded});
}
そして、HTMLが読み込まれるときに呼ばれるように指定しているentryPageLoaded内で検索を行っています。
そのentryPageLoaded関数は、以下のような感じです。
var BlogEntry = Class.create();
BlogEntry.prototype = {
initialize : function(title, content, date, url){
this.title = title;
this.content = content;
this.date = date;
this.url = url;
},
search : function(keyword){
var re = new RegExp('('+keyword+')', 'ig');
var r;
if((r=re.exec(this.content))){
var i = r.index;
i = (i > 25) ? (i-20) : i;
var l = (this.content.length-i > 100) ? 90 : this.content.length-i;
return "..." + this.content.substr(i, l).replace(re, '<b>\$1</b>') + "...";
}
return "";
}
};
var entryCache = [];
function entryPageLoaded(r)
{
var text = r.responseText.replace(/[\r\n]/g, "");
var pt1 = '<div class="entry-top">.*?<div class="entry-bottom"></div>.*';
var re1 = new RegExp(pt1, "gi");
var pt2 = '<div class="entry">.*<h3>(.*?)</h3>';
pt2 += '.*<div class="entry-body-text">(.*?)<div class="entry-body-bottom"></div>.*';
pt2 += '<span class="post-footers">(.*?)<a href.*<a class="permalink" href="(.*?)">';
var re2 = new RegExp(pt2, "gi");
var results = text.match(re1);
for(var i=0;i<results.length;i++){
results[i].match(re2);
var title = RegExp.$1;
var content = RegExp.$2;
var date = RegExp.$3;
var url = RegExp.$4;
content = content.replace(/<.*?>/gi, "");
var blogEntry = new BlogEntry(title, content, date, url);
entryCache.push(blogEntry);
searchEntry(blogEntry);
}
}
まず最初のBlogEntry = Class.create();の部分ですが、これはPrototype.jsの機能で、このように書くとクラスを定義することが出来ます。
このBlogEntryというクラスでは、記事のタイトル・内容・日付・URLを持つプロパティと、searchという検索を行うメソッドを定義しています。
切り出した各々の記事からこのBlogEntryクラスを生成し、その後に定義してあるentryCacheという配列に格納することで2回目以降の検索を高速化することが目的です。
月別にアーカイブされたページのHTMLの構成は、
<div class="entry-top">
....<div class="entry">.....<h3>1つ目の記事のタイトル</h3>....
....<div class="entry-body-text">1つ目の記事の内容<div class="entry-body-bottom"></div>
....<span class="post-footers">1つ目の記事の日付<a href="...">.....<a class="permalink" href="1つ目の記事のURL">....
...........
....<div class="entry">.....<h3>2つ目の記事のタイトル</h3>....
....<div class="entry-body-text">2つ目の記事の内容<div class="entry-body-bottom"></div>
....<span class="post-footers">2つ目の記事の日付<a href="...">.....<a class="permalink" href="2つ目の記事のURL">....
<div class="entry-bottom"></div>
のようになってます。
このような構成のHTMLから記事だけを抽出するために、entryPageLoaded関数では、まず<div class="entry-top">から<div class="entry-bottom"></div>までを切り出し、その結果から記事のタイトルや内容を抽出する作業をforループ内で繰り返し行っています。
記事の内容に関しては、HTMLタグが含まれていますのでタグが検索にヒットしないように、
content = content.replace(/<.*?>/gi, "");
の部分でHTMLタグを除去しています。
長い道のりでしたが、これでやっと記事の抽出まで完了しました。
この後は検索を行い結果を表示する部分ですが、長くなってしまいましたので続きはまた明日書きたいと思います。