Kill one bird with two stones.

情報推薦、情報抽出を研究している大学院生の基本的にやったことのメモとか

WikipediaのアブストラクトデータをDBに突っ込む

DBはMySQLを使う。
データのダウンロードは、
Index of /jawiki/latest/
jawiki-latest-abstract.xml

右クリックメニューから保存

でダウンロードしておく。左クリックからだと設定にもよるけど、とてつもなく大きいxmlファイルを開きに行っちゃうので注意。(というより開けないとおもうけど)

で、このabstractをmysqlでインポートできるようにしたいわけだけど、
jawiki-latest-pages-articles.xml.bz2
だとxml2sqlを使えば簡単にできるらしいんだけど、無理そうだったので自作のパーサーを書く。
JavaでXMLを操作の4種類方法とサンプルソース | DigiTechLog Dot Com
のSAXパーサーと
ファイルの入出力 ( Javaサンプル集 )
の追加書き込みの記事を参考に作った。

バグとかありそうだけど、一応パーサーとしての役割を果たしているし、
ひとまず良しとしておく。
ソースは

import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;

public class XMLTestApp1 extends DefaultHandler {
	public static void main(String[] argv) {
		try {
			SAXParserFactory spfactory = SAXParserFactory.newInstance();
			SAXParser parser = spfactory.newSAXParser();
			parser.parse(new File("jawiki-latest-abstract.xml"),
					new XMLTestApp1());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public int key = 0;
	public String titlename = "";
	String anchor = "";
	String abst = "";
	String[] Starray = new String[2];
	int akey = 0;
	boolean flag = false;

	public void startElement(String uri, String localName, String qName,
			Attributes attributes) {
		if (qName.equals("title")) {
			key = 1;
			abst = "";
		} else if (qName.equals("abstract")) {
			key = 2;
			akey = 0;
		} else if (qName.equals("anchor")) {
			key = 3;
		} else {
			key = 0;
			akey = 0;
			String[] Starray = new String[2];
		}
	}

	public void characters(char[] ch, int offset, int length) {
		if (key == 1) {
			titlename = new String(ch, offset, length);
			if (titlename.length() > 10) {
				titlename = titlename.substring(10);
				Starray[0] = titlename;
				akey = 1;
				flag = false;
			}

		} else if (key == 2) {
			akey = 0;
			abst = abst + new String(ch, offset, length);
			int abstcount = abst.length();
		} else if (key == 3) {
			Starray[1] = abst;
			akey = 2;
			anchor = new String(ch, offset, length);
			String outputFileName = "link.txt";
			File outputFile = new File(outputFileName);
			try {
				// 出力ストリームの生成(追記モード)
				FileOutputStream fos = new FileOutputStream(outputFile, true);
				OutputStreamWriter osw = new OutputStreamWriter(fos);
				PrintWriter pw = new PrintWriter(osw);
				pw.println(Starray[0] + "," + anchor);
				pw.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (akey == 2 && flag == false) {
			flag = true;
			String outputFileName = "abst.txt";
			File outputFile = new File(outputFileName);
			try {
				FileOutputStream fos = new FileOutputStream(outputFile, true);
				OutputStreamWriter osw = new OutputStreamWriter(fos);
				PrintWriter pw = new PrintWriter(osw);
				pw.println(Starray[0] + "," + Starray[1]);
				pw.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			akey = 3;
		}
	}

	private static boolean checkBeforeWritefile(File file) {
		if (file.exists()) {
			if (file.isFile() && file.canWrite()) {
				return true;
			}
		}
		return false;
	}
}

読み込ませたいxmlをプログラム上で指定して、書き出したいファイル二つをプログラムを置いたところに作成しておく。
自分はabst.txt とlink.txt

abst.txtは
title,abstract の形式で出力され、linkは title,linkで出力される。
あらかじめデーターベースを作成しておいて
次にmysqlimportで
$ mysqlimport -i -u root -p --fields-terminated-by="," データベース名 ファイル名
Password:***

でインポートしてデータを見てみればたぶんOK

ただ、,区切りで判断してるから&のアブストラクトがいまいちちゃんと処理できていない。+とかで区切り文字にしておけばいいんだろうけど。

あとアブストラクトのデータをちょっと見るとわかるけどいまいち使えない。
中途半端にアブストラクトが切り出されているものも多いし。
やっぱり文章使いたいなら jawiki-latest-pages-articles.xml.bz2を使っておくべき