ニコニコ大百科の言葉を PC に覚えさせる前準備

ニコニコ大百科の言葉をPCに覚えさせるとこうなる‐ニコニコ動画(ββ) からです。 ここでは Ruby スクリプトでニコニコ大百科トップページ - ニコニコ大百科のインデックスからでーたを取得して TSV を作成しているようですが、ここでは w3m と gawk を使ってみます。

w3m はテキストベースのブラウザとして知られていますが、dump 機能を使うことで HTML の処理ではなくテキストの処理として扱うことが簡単にできるようになる場合があります。 問題としては w3m のビルド方法などによって箇条書きのキャラクターが異なったりする点があります。 ここでは 50音順タイトル表示 - ニコニコ大百科にアクセスした際に以下のように表示される w3m を使っています。

50音順タイトル表示

  • ア
      □ あ(絵師) (ア) : 2009/04/27(月) 00:58:51
      □ あ、 (ア) : 2008/08/21(木) 15:04:22
      □ あ (ア) : 2009/03/17(火) 07:29:42
      □ retto (ア) : 2009/01/12(月) 12:32:20
      □ あ? (ア) : 2009/04/18(土) 18:38:09
      □ あ(゚д゚) (ア) : 2009/03/23(月) 16:57:36 (リダイレクト)
      □ あぁ! (アァ) : 2008/07/11(金) 23:00:53

さて gawk スクリプトは以下のようになります。

#! /usr/bin/gawk -f
# nikopedia.awk

BEGIN {
    OFS           = "\t";
    w3m_cmd       = "/usr/bin/w3m";
    w3m_opt       = "-dump";
    w3m_li_char   = "□ ";
    index_kana    = "アイウエオカキクケコサシスセソタチツテトナニヌネノ"\
                    "ハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォ"\
                    "ャュョガギグゲゴザジズゼゾダヂヅデドバビブベボ"\
                    "パピプペポ";
    index_hira    = "あいうえおかきくけこさしすせそたちつてとなにぬねの"\
                    "はひふへほまみむめもやゆよらりるれろわをんぁぃぅぇぉ"\
                    "ゃゅょがぎぐげござじずぜぞだぢづでどばびぶべぼ"\
                    "ぱぴぷぺぽ";
    nikopedia_url = "http://dic.nicovideo.jp/m/yp/";

    num_kana = split(index_kana, arr_kana, "");
    num_hira = split(index_hira, arr_hira, "");

    ##for (i = 1; i <= num_kana; i++) {
    for (i = 1; i <= 1; i++) {
        w3m_exec = w3m_cmd " " w3m_opt " " nikopedia_url arr_kana[i];

        while (w3m_exec | getline > 0) {
            if ($0 ~ w3m_li_char) {
                sub(/^\(/, "", $3);
                sub(/\)$/, "", $3);
                print sed_y(index_kana, index_hira, $3), $2, "名詞";
            }
        }
        close(w3m_exec);
    }
}

# sed の y コマンドと同じような働きをする置換コマンド
#   in:     str1:   置換前文字列
#   in:     str2:   置換後文字列
#   in:     obj:    置換対象文字列
#   out:    置換対象文字列を置換した文字列
function sed_y(str1, str2, obj,
               num_str1, num_str2, arr_str1, arr_str2, func_name, i) {
    func_name = "sed_y";

    num_str1 = split(str1, arr_str1, "");
    num_str2 = split(str2, arr_str2, "");
    if (num_str1 != num_str2) {
        print func_name "str1, と str2 の長さが違います。";
        exit 1;
    }

    for (i = 1; i <= num_str1; i++) {
        gsub(arr_str1[i], arr_str2[i], obj);
    }

    return obj;
}

ここではカタカナをひらがなに変換するのが面倒なので、sed の y コマンドに似た sed_y 関数を作って変換しています。 毎回 split() 関数で分割するのは効率が悪いのですが、他のプログラムでも気軽に使えるように故意に毎回分割しています。

さて、実行ですが、上の

##for (i = 1; i <= num_kana; i++) {
for (i = 1; i <= 1; i++) {

for (i = 1; i <= num_kana; i++) {
##for (i = 1; i <= 1; i++) {

にすれば一気に落としてくれると思いますが、それなりに負荷をかけそうなのと、特にエラー処理をしているわけではありませんので、実際の使用では十分に注意してください。 無保証です。

さて、実行してみます。

$ gawk -f nikopedia.awk
あ      あ(絵師)        名詞
あ      あ、    名詞
あ      あ      名詞
あ      retto   名詞
あ      あ?     名詞
あ      あ(゚д゚)       名詞
あぁ    あぁ!   名詞
<snip>

上記のように TSV ファイルが出力されます。

w3m の dump 機能と awk を使った例を示しましたが、w3m の dump 機能と awk を使うことで HTML を扱うことができない awk でも簡単に HTML が扱えるようになります。

tag_gawk.pngtag_gawk.png