2006 年 8 月 10 日 22 時 17 分

写真


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


mixi の日記には、写真をアップロードすることができる。
日記一覧画面や日記詳細画面では、
写真のサムネイルが表示され、
クリックすると新しいウィンドウが開いて表示される。

例えば、この日記は、3 枚の写真(画像)を載せている。

http://mixi.jp/view_diary.pl?id=143434156&owner_id=2300658

現在解析しているのは HTML だけなので、
写真を取り出すためには、まずは画像のタグを検出し、
写真が格納されている URL を得る必要がある。

日記一覧ページの場合、本文の要約が始まる箇所に
<td CLASS=h120> があり、その下に空行があるが、
写真をアップロードしている場合は、
空行部分に非常に長い table が挿入される。

写真は img タグを使って挿入され、
img の src にはサムネイルの URL が、
そして、img を取り囲むリンクの onclick 属性には、
新しいウィンドウを開いて写真を表示する URL がある。

正規表現を考えてみよう。

メインの写真: /show_picture.pl\?img_src=(.*?)','pict'/
サムネイル: /<img src=(.*?) border=0>/

これらを組み合わせて、
MixiDiary クラスの正規表現を見直すとこうなる。

    // タイトル・写真のタグ・ID・OwnerID を取り出す正規表現
    this._rex = new RegExp(
            "<td bgcolor=#F2DDB7>&nbsp;([\\w\\W]*?)</td></tr>"
            + "[\\w\\W]*?"
            + "<td CLASS=h120>\n"
            + "(<table>.*</table>)?"
            + "[\\w\\W]*?"
            + "<a href=\"view_diary.pl\\?id=(\\d+)&owner_id=(\\d+)\">続きはこちら</a>", "ig");

    // 写真とサムネイルの URL を取り出す正規表現
    this._rexImages = new RegExp(
            "show_picture.pl\\?img_src=(.*?)','pict'"
            + ".*?<img src=(.*?) border=0>", "ig");

写真は数が不定なので、メインの正規表現では、
<td CLASS=h120> の次の行に、
<table>~</table> がくる場合のみキャプチャしておく。
写真がない場合は、キャプチャは空文字列になるのだ。

そして、<table>~</table> の中身は、
_rexImages を使って別に解析する。

そして、MixiDiaryIterator.prototype.next も書き換える。

    // 日記を取り出す
    var entry = this._entries.shift();
   
    // 写真の URL を取得し、配列に格納
    var images = [];

    if (entry[2].length > 0) {
        this._rexImages.lastIndex = 0;
        for (;;) {
            var match = this._rexImages.exec(entry[2]);
            if (match == null) break;

            // 配列要素は、とりあえず写真とサムネイルの
            // URL を連結した文字列。
            images.push(match[1] + " " + match[2]);
        }
    }

    // 日記オブジェクトを作成して返す
    return new MixiDiaryEntry(
            this._session, parseInt(entry[8], 10),
            parseInt(entry[9], 10), entry[1], images);

写真の URL は配列に入れておく。
後でちゃんと設計するので中身は適当。まずはテストだ。

例によって、images は MixiDiaryEntry に渡し、
MixiDiaryEntry のプロパティとして機能させる。

MixiDiaryEntry も書き換えよう。

    function MixiDiaryEntry(session, id, ownerID, title, images) {

        this._session = session;
        this._id = parseInt(id, 10);
        this._ownerID = parseInt(ownerID, 10);
        this._title = String(title);
        this._images = images;

        // その他フィールド
        this._date = undefined;
        this._content = undefined;
    }

    // 写真を返す
    MixiDiaryEntry.prototype.getImages = function () {
        return this._images;
    }

MixiDiaryEntry のコンストラクタの引数に、
image を追加し、フィールドとして格納しておく。
そしてアクセサ getImages を追加し、
コンストラクタで受け取った配列をそのまま返しておく。
そうしておけば MixiDiaryEntry は後で修正不要となる。

そして、テストのため、Main.js の出力部分を書き換える。

    WScript.Echo("================================");
    WScript.Echo("タイトル: " + item.getTitle());
    WScript.Echo("写真: " + item.getImages().join(", "));
    WScript.Echo("================================");

いちいち日記ページにアクセスすると大変なので、
タイトルと写真の URL だけを取り出してみよう。

では、実行してみる。

(一部抜粋)

================================
タイトル: 中心を基準に回転
写真: http://ic22.mixi.jp/photo/diary/3/39/98360339_56.jpg http://ic22.mixi.jp/photo/diary/3/39/98360339_56s.jpg
================================
================================
タイトル: 任意角度の回転
写真: http://ic21.mixi.jp/photo/diary/14/55/97871455_219.jpg http://ic15.mixi.jp/photo/diary/14/55/97871455_219s.jpg, http://ic23.mixi.jp/photo/diary/14/55/97871455_194.jpg http://ic21.mixi.jp/photo/diary/14/55/97871455_194s.jpg
================================
================================
タイトル: 画像の回転
写真:
================================
================================
タイトル: 線形補間法の特徴
写真:
================================

よし、URL を抜き出すことができたようだ。

さて、ある程度役者はそろってきた。
そろそろファイルに出力することを考えるかな。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.