最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
エクスポータという名前が付く以上、
データを何かしらの形でエクスポートしなければならない。
開発者にとっては、XML で出力すれば便利だろう。
XSLT なり DOM なり使って自由に操れるので。
でも、人が読むバックアップ用途としてみると、
XML なんて吐かれても使えねぇ。利用者としては
エクスポートした後も簡単に読めるようにしたい。
さて、どうしようか。
mixi の日記には、写真をアップロードすることができる。
日記一覧画面や日記詳細画面では、
写真のサムネイルが表示され、
クリックすると新しいウィンドウが開いて表示される。
例えば、この日記は、3 枚の写真(画像)を載せている。
http://mixi.jp/view_diary.pl?id=143434156&owner_id=2300658
現在解析しているのは HTML だけなので、
写真を取り出すためには、まずは画像のタグを検出し、
写真が格納されている URL を得る必要がある。
HTML には、実体参照と呼ばれる仕組みがある。
& や @ 等がそれだ。
正確には、前者を文字実体参照、後者を数値文字参照と呼ぶ。
乱暴な言い方をすると、HTML のエスケープ構文である。
今までの設計では、日記やタイトルを取得する際には、
正規表現を使って HTML を直接解析していたが、
実体参照に関しては考慮していなかった。
なので、MixiDiaryEntry#getContent メソッドで、
日記の本文を取得した場合は、< 等の実体参照や、
mixi が自動的に挿入した <br> タグが含まれている。
日記は、view_diary.pl にアクセスすることで取得できる。
このページでは、完全な形で日記を見ることができる。
view_diary.pl の URL のパラメータには、
日記の ID だけでなく、著者の ID も渡す必要があるが、
これら ID は、日記一覧ページから取得できるので問題ない。
では、まずはページを取得して HTML を眺めてみよう。
var session = new MixiSession(
"自分のメールアドレス", "パスワード", 3000);
mixi では日記一覧ページはページャ処理されており、
30 項目ごとに分けて個別のページとなっている。
全ての日記一覧を得るためには、
全てのページを順番に取得していく必要がある。
日記一覧を管理している list_diary.pl には、
「page」というパラメータがあり、
それでページ番号を渡す仕様になっている。
先頭ページ番号は 1 となっているので、
list_diary.pl?page=1 でも最初の 30 項目が出てくる。
例外クラスの設計が終わったところで、
MixiSession クラスを自動化プログラム用に改変しよう。
今回盛り込むのは以下の要素だ。
・通信失敗、ログイン失敗などの例外処理
・連続リクエストを防ぐための待ち処理
まず、コンストラクタだ。
待ち時間はコンストラクタで外部から受け取る事にしよう。
引数に wait を追加して、ミリ秒単位の数値を受け取る。
なんか継承で長々とやってるな。もう一息。
プロトタイプを継承する方法は分かった。
プロトタイプには、主にメソッドが登録されているため、
親クラスのメソッドを継承することができる。
では、インスタンスプロパティなど、
プロトタイプに定義されていないものを
親クラスから継承するにはどうすればよいか。
Java や C# では、派生クラスのコンストラクタから、
基底クラスのコンストラクタを呼び出すことで、
基底クラスが持つインスタンスフィールドの値を継承する。
Error インスタンスをプロトタイプとすると、
目に見えない悪影響を及ぼす可能性があることが分かった。
では次の手を考えてみよう。
Error プロトタイプを参照するオブジェクトを得るためには、
Error プロトタイプを prototype プロパティにもつ、
コンストラクタからインスタンスを作成するしかない。
Error インスタンスもこれに該当するが、
Error コンストラクタがどういう処理を行うかが、
分からないので問題が起きる可能性があった。
MixiError を Error から継承するためには、
MixiError のプロトタイプチェーンに
Error プロトタイプを追加すればよいことがわかった。
つまり、次のようなチェーンになれば良い。
MixiError インスタンス
⇒MixiError プロトタイプ
⇒Error プロトタイプ
⇒Object プロトタイプ
昨日の MixiError 型は、例外としては利用できるのだが、
以下のような課題を抱えている。
・MixiError は Error 型とはみなされない。
new MixiError() instanceof Error が false になる。
・Error 型で定義されているメソッドと同様のものを、
いちいち実装しなおすという手間がかかる。
特に前者は、ポリモルフィズムを利用して、
Error 型から派生した例外を利用する際に問題となる。