すぐに使える2chブラウザの作り方

仕事中のちょっと暇な時に、Twitterやらfacebookやらを確認することはあると思うんだけど、
最近ちょっとどころではないほど暇なので、2chもチェックできればいいなと思い始めた。


だが、2chのページを直接表示するのは職場では気が引けるし、専ブラをインストールするわけにもいかないので、Javascriptベースでインストール不要のブラウザアプリをつくってみることにした。


まずは、板の一覧が必要だが、これは
5ちゃんねる掲示板リスト
ここで取得する。

<A HREF=http://www.2ch.net/>2chの入り口</A>
/<A HREF=http://info.2ch.net/guide/>2ch総合案内</A>

こんな感じで一覧になっているので、正規表現などを使って
<option&t;タグの入り欄に変換する


板の一覧の次は、スレの一覧。スレの一覧はsubject.txtに含まれていて、
このURLは

板URL + “subject.txt”

参考http://www.hoge256.net/2007/07/56.html


各スレのdatファイルは

板URL + “dat/9999999.dat”
※9999999はスレッドNo。

参考http://www.hoge256.net/2007/07/56.html


これで、全ての準備完了!!
あとは、これらのURLからデータを取ってきて加工するだけと思っていたが、このあとクロスドメインの壁というラスボスが待ち構えていた。
今回作成するJavascriptは、ローカルのPCかもしくは、自分のサーバに載せることを想定しており、当然のことながら2chのサーバに載せるわけではない。
そうなると、Jacascriptの置いてあるドメインと、情報の取得元のドメインがことなってしまい、Ajaxやiframe等を使った情報の取得が出来なくなってしまう。


多くのサイトでは、

  • 自分の管理するサーバ(Javascriptを置くサーバ)に、リクエストを中継するプロキシアプリを実装する
  • JSONP形式でサーバからデータを返す

ことで解決することを提唱しているが、ちょっとめんどくさいのと情報取得元のサーバをいじれないので、別の方法を探していたところ見つけたのがこれ
Cross-domain requests with jQuery – James Padolsey

$.ajax({
url: 'http://news.bbc.co.uk',
type: 'GET',
success: function(res) {
var headline = $(res.responseText).find('a.tsh').text();
alert(headline);
}
});

こんな感じで、クロスドメイン問題を解決し、他のドメインから情報を取得出来るらしい。
仕組みとしては、上記の2つの方法の合わせ技となっている。
拡張されたajax呼び出しのコードは以下の通り

jQuery.ajax = (function(_ajax){

var protocol = location.protocol,
hostname = location.hostname,
exRegex = RegExp(protocol + '//' + hostname),
YQL = 'http' + (/^https/.test(protocol)?'s':'') + '://query.yahooapis.com/v1/public/yql?callback=?',
query = 'select * from html where url="{URL}" and xpath="*" and charset="Shift_JIS"';

function isExternal(url) {
return !exRegex.test(url) && /:\/\//.test(url);
}

return function(o) {

var url = o.url;

if ( /get/i.test(o.type) && !/json/i.test(o.dataType) && isExternal(url) ) {

// Manipulate options so that JSONP-x request is made to YQL

o.url = YQL;
o.dataType = 'json';

o.data = {
q: query.replace(
'{URL}',
url + (o.data ?
(/\?/.test(url) ? '&' : '?') + jQuery.param(o.data)
: '')
),
format: 'xml'
};

// Since it's a JSONP request
// complete === success
if (!o.success && o.complete) {
o.success = o.complete;
delete o.complete;
}

o.success = (function(_success){
return function(data) {

if (_success) {
// Fake XHR callback.
_success.call(this, {
responseText: data.results[0]
.replace(/

つまり、YQL経由で対象のデータを取得し、かつ、YQLからの戻りをJSONP形式にすることでクロスドメインの問題を解決しているようだ。

query = 'select * from html where url="{URL}" and xpath="*" and charset="Shift_JIS"';

これを使えばデータが取得できるが、日本語が文字化けするので、最後の部分に「charset="Shift_JIS"」を追加した。


で、後は実際にsubject.txtとdatファイルを上記の方法で取得して、加工すれば完了

        function selectBoard(){
$.ajax({
url: $("#board").val() + "/subject.txt",
type: 'GET',
success: function(res) {
re = new RegExp("<p>.+</p>");
var contents = res.responseText.match(re)[0];
contents = contents.replace("<p>","");
contents = contents.replace("</p>","");

$("#thread").empty();
var theradarray = contents.match(/[0-9]*\.dat.+?\([0-9]+\)/g);
jQuery.each(theradarray, function(i, val) {
var threaditem = val.split("&lt;&gt;");
$("<option value='" + threaditem[0] + "'>" + threaditem[1] +"</option>").appendTo("#thread");

})
}
});
}

function selectThread(){

$.ajax({
url: $("#board").val() + "/dat/" + $("#thread").val(),
type: 'GET',
success: function(res) {
re = new RegExp("<p>.+</p>");
var contents = res.responseText
contents = contents.replace("<html>","");
contents = contents.replace("</html>","");
contents = contents.replace("<p>","");
contents = contents.replace("</p>","");
contents = contents.replace("<body>","");
contents = contents.replace("</body>","");
contents = contents.replace("<head>","");
contents = contents.replace("</head>","");
contents = contents.replace("<title/>","");
contents = contents.replace(/<meta.*>/,"");
contents = contents.split("&lt;&gt;").join("<br/>")
$("#threadContents").html(contents);
}
});
}

というわけで作ってみたのがこちら
2ch browser