KazMuzik.net
Music / Technology / Healthcare / Immigration / アメリカ
Google
 
<< Kaz Muzik Blog Backup Project #6Japanese Character Utility #1 - カタカナ <-> ひらがな >>

my ContentGetter class - Kaz Muzik Blog Backup Project #7 - KazMuzik Blog
2007-04-22 10:01

前回までで、Nutch を使って、ブログのコンテンツを segment にセーブするところまではできました。今回は、segment から、URL を指定して、自由にコンテンツを get するクラスを実装します。nutch のサブコマンド readseg でとれないこともありませんが、今後の利用を考えると、オブジェクトとして実装したいところです。

まずは、readseg の main() メソッドをもつ SegmentReader クラスのサブクラスとして簡単に実装しようと思い、src/java/org/apache/nutch/segment/SegmentReader.java から始めてみました。不用なコードをどんどん消去していくうちに、nutch や hadoop のクラスについて、だんだん理解が深まり、結局、スクラッチから書くことにしました。実際には、org.apache.nutch.protocol.Content クラスにも main() メソッドがあり、同様なことをすることがわかりました。しかし、これはレコード番号から Content をとるので、URL から Content をとるには、SegmentReader の一部のコードを使う必要があります。
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.io.MapFile;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapred.MapFileOutputFormat;
import org.apache.nutch.protocol.Content;
import org.apache.nutch.util.NutchConfiguration;

public class ContentGetter extends Configured {

  private FileSystem fs;

  // public ContentGetter() { super(null); }

  public ContentGetter(Configuration conf) {
    super(conf);
    try {
      this.fs = FileSystem.get(getConf());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public byte[] getContent(final Path segment, final Text key) throws Exception {
    Path dir = new Path(segment, Content.DIR_NAME);
    MapFile.Reader[] readers = MapFileOutputFormat.getReaders(fs, dir, getConf());
    if (readers == null || readers.length != 1) {
      return null;
    }

    Content value = new Content();
    readers[0].get(key, value);
    readers[0].close();

    return value.getContent();
  }

  public static void main(String[] args) throws Exception {
    if (args.length < 2) {
      usage();
      return;
    }
    String input = args[0];
    String key = args[1];
    //
    Configuration conf = NutchConfiguration.create();
    ContentGetter contentGetter = new ContentGetter(conf);
    byte[] content = contentGetter.getContent(new Path(input), new Text(key));
    System.out.write(content);
    System.out.flush();
    return;
  }

  private static void usage() {
    System.err.println("Usage: ContentGetter segment url");
  }
}

$ javac -classpath nutch-0.9.jar:lib/hadoop-0.12.2-core.jar ContentGetter.java
$ 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:conf  \
ContentGetter crawl-3/segments/20070421201803 http://kazuomik.livejournal.com/495.html \
> 495.html
$

ブラウザで、直接 /usr/local/nutch-0.9/495.html を表示させたところ、きちんと表示されました。

なお、Nutch は、以前書いたように、かなり Hadoop に依存していますが、Hadoop の特徴としては、Distributed File System の他に、MapRecuce プログラミングモデルがあります。今回のソースでは利用していませんが、SegmentReader のソースをいじっているうちに、副産物として理解することができました。



つづく

*

Tags: computer_technology, programming