KazMuzik.net
Music / Technology / Healthcare / Immigration / アメリカ
Google
 
<< Diet Code plusLiveJournalEntryExtractor - Kaz Muzik Blog Backup Project #10 >>

LiveJournalEntryFilterReader - Kaz Muzik Blog Backup Project #9 - KazMuzik Blog
2007-04-28 22:48

今回は、livejournal.com の HTML から、エントリだけを抜き出すクラスを実装します。ひとつのエントリは次のようになっています。

4/21/2007 に書いたように、エントリは <a name="itemNNNN"></a> というラインから始まっています。次に TABLE があり、これは日付と時刻のある背景が深緑の部分です。その次の TABLE は、その下のまわりがうすい青緑の部分です。その内側に TABLE があり、背景が白い部分で、エントリのタイトルや本文、Tag(s)などが含まれています。今回は、<a name="itemNNNNN"></a>, 日付のある TABLE, タイトル、本文のある TABLE だけを抜き出すことにします。

java.io.FilterReader を extend しようと思いましたが、必要なのは readLine() メソッドだけなので、簡単に BufferedReader を extend しました。
import java.io.BufferedReader;
import java.io.Reader;
import java.io.InputStreamReader;
import java.io.IOException;

public class LiveJournalEntryFilterReader extends BufferedReader {
  private boolean item = false;
  private int nTableTag = 0;
  private int nTableLevel = 0;

  public LiveJournalEntryFilterReader(Reader in) {
    super(in);
    item = false;
    nTableTag = 0;
    nTableLevel = 0;
  }

  public String readLine() throws IOException {
    while (true) {
      String line = super.readLine();
      if (line == null) {
        return null;
      }
      if (! item) {
        if (line.indexOf("<a name=\"item") >= 0) {
           item = true;
           nTableTag = 0;
           nTableLevel = 0;
           return line;
        }
        continue;
      }

      if (line.indexOf("<table") >= 0) {
        if (nTableLevel == 0) {
          nTableTag ++;
        }
        nTableLevel ++;
      }

      if (line.indexOf("</table>") < 0) {
        if (nTableTag == 1 && nTableLevel >= 1) {
          return line;
        }
        if (nTableTag == 2 && nTableLevel >= 2) {
          return line;
        }
        continue;
      }
      else {
        nTableLevel --;
        if (nTableTag == 1 && nTableLevel >= 0) {
          return line;
        }
        if (nTableTag == 2 && nTableLevel >= 1) {
          return line;
        }
        if (nTableTag == 2 && nTableLevel == 0) {
          item = false;
          nTableTag = 0;
        }
        continue;
      }
    }
  }

  public static void main(String[] args) throws Exception {
    LiveJournalEntryFilterReader in
      = new LiveJournalEntryFilterReader(
          new InputStreamReader(System.in, "UTF-8"));
    while (true) {
      String line = in.readLine();
      if (line == null) {
        break;
      }
      System.out.println(line);
    }
  }
}

特に、コメントするほどのこともないプログラムです。4/22 の ContentGetter を使って 2876.html を作って実行してみます。
$ java -classpath .:nutch-0.9.jar:lib/hadoop-0.12.2-core.jar:\
lib/commons-logging-1.0.4.jar:lib/log4j-1.2.13.jar ContentGetter \
crawl-3/segments/20070421201803 http://kazuomik.livejournal.com/2876.htm > 2876.html
$ javac LiveJournalEntryFilterReader.java
$ cat 2876.html | java  LiveJournalEntryFilterReader > 2876x.html



多少そっけなくなりましたが、エントリの情報は落ちていません。

Tags: computer_technology, programming