このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
今日は、最新日記一覧ページの HTML を取得し、
日記の情報を抜き出してみよう。
最新日記一覧ページには色々な情報があるが、
mixi の HTML は、人間が読むために最適化されているため、
要点だけ抜き出すためには、HTML を解析する必要がある。
日記の情報を取り出すためには幾つかの方法があるが、
今日は、昔からの文字列処理を使ってみる。
前後のテキストを手ががりとして、
取り出したい情報を抜き出すことにしよう。
まず、HTML のソースをじっくり眺めてみる。
日記一覧ページからは、日記の以下の情報が取り出せそうだ。
・日時
・タイトル
・本文の先頭部分
日付は「<font COLOR=#996600>」の後から始まり、
「<br>」の前までだ。
時間はその「<br>」の後から始まり、
「</font>」の前までだ。
タイトルは「<td bgcolor=#F2DDB7> 」の後から始まり、
「</td>」の前までだ。
本文要約は「<td CLASS=h120>改行」の後から始まり、
「改行<br>改行改行</td>」の前までだ。
日記の最初に来るのは日付であり、
その後に時間、タイトル、本文要約と続く。
日付の「<font COLOR=#996600>」というのは一般的なので、
日付以外の場所で使われる危険性はあるのだが、
HTML を調べても日付以外では使用されていないようだ。
ま、どの道 mixi の仕様が変われば対応しなおしなので、
今回は上記を基準として考えよう。
では、テスト用のコードを書いてみよう。
========== Main.js ==========
// 文字列に挟まれた文字列とその最後の位置を配列で返す
function _extract(string, preMatch, postMatch, index) {
// 直前のパターンを探す
var start = string.indexOf(preMatch, index);
if (start == -1) return null;
// データの開始位置はパターンの後
start += preMatch.length;
// 直後のパターンを探す
var end = string.indexOf(postMatch, start);
if (end == -1) return null;
// 発見
return [string.substring(start, end), end];
}
function main() {
// ログイン
var session = new MixiSession(
"自分のメールアドレス", "パスワード");
// 日記一覧ページの HTML を取得
var html = session.fetch("http://mixi.jp/list_diary.pl");
// HTML 解析の手掛かりを用意
// 日付の前後の HTML
var PRE_DATE = "<font COLOR=#996600>";
var POST_DATE = "<br>";
// 時間の前後の HTML
var PRE_TIME = "<br>";
var POST_TIME = "</font>";
// タイトルの前後の HTML
var PRE_TITLE = "<td bgcolor=#F2DDB7> ";
var POST_TITLE = "</td>";
// 要約の前後の HTML
var PRE_SUMMARY = "<td CLASS=h120>\n";
var POST_SUMMARY = "\n<br>\n\n</td>";
// 次の検索位置
var next = 0;
for (;;) {
// 日付を探す
var date = _extract(html, PRE_DATE, POST_DATE, next);
if (date == null) break;
// 時間を探す
var time = _extract(html, PRE_TIME, POST_TIME, date[1]);
if (time == null) break;
// タイトルを探す
var title = _extract(html, PRE_TITLE, POST_TITLE, time[1]);
if (title == null) break;
// 要約を探す
var summary = _extract(html, PRE_SUMMARY, POST_SUMMARY, title[1]);
if (summary == null) break;
// 日記発見!
// テスト出力
WScript.Echo("================================");
WScript.Echo("日時: " + date[0] + " " + time[0]);
WScript.Echo("タイトル: " + title[0]);
WScript.Echo("--------------------------------");
WScript.Echo(summary[0]);
WScript.Echo("================================");
// 次の検索位置を決める
next = summary[1] + POST_SUMMARY.length;
}
}
main();
========== end of Main.js ==========
文字列の検索は、String 型が持つ、
indexOf メソッドを使うのが基本となる。
indexOf は文字列の中に含まれる文字列を検索し、
見つかった文字列の先頭の位置を返す。
そのままコードを書くと indexOf だらけになるので、
2 つの文字列の間に挟まれた文字列を検索する、
関数 _extract を作成することにした。
_extract では、string の index 番目から、
preMatch と postMatch で挟まれる文字列を検索し、
見つかれば、その挟まれた文字列と、
挟まれた文字列の最後の位置を配列で返す。
見つからなければ null を返す。
関数からは複数の値を返したいので、
Perl のように配列を返すようにした。
JavaScript でも大括弧を使って配列リテラルが書けるのだ。
main では、日付・時間・タイトル・要約の 4 項目に対して、
パターンとなる文字列を決めておき、
それを基準として順番に抜き出している。
全て抜き出せた場合は、日記が見つかったので、
テストのために画面出力している。
では、実行してみよう。
================================
日時: 07月27日 22:38
タイトル: 最新日記一覧ページの取得
--------------------------------
さて、長々と脱線していたので、話を軌道に<br>戻そう。今日は MixiSession の実装をする<br>。まず、以前作った _encodeForm 関数を、
================================
================================
日時: 07月26日 18:27
タイトル: プロトタイプ
--------------------------------
JavaScript はオブジェクト指向である。し<br>かし、Java や C# のようなクラスベースで<br>はなく、プロトタイプベースの言語である。
================================
(以下省略)
よし、目的に近づいてきた。