ruby1.9+nokogiriでWikipedia内を探索してみた(副題:”魔王”という単語の含まれるラノベ一覧を調べたかった)


ふと、最近にライトノベルのタイトルに”魔王”という単語が入っている作品最近多いようなと思って、どうにかしてそれを調べるコードが書けないかと思い立ったので、以前から触ろうと思っていたrubyのライブラリであるnokogiriを使って、Wikipedia内のリストから探索して、それをおこなってみました。

導入や実際作成したコードは以下より…

きっかけと導入

前述したように、最近ライトノベルコーナーを見ていると、”勇者”とか”魔王”って単語がタイトルに含まれる作品を多く見るようになってきた気がして、実際どれくらいあるのか調べてみたくなったため、rubyのnokogiriを利用して、リストを解析、一覧化するコードを書こうと思い立ちました。

しかしながら、まずnokogiriの導入で結構躓いたので、試行錯誤のうえ、うまくいったやり方を以下にまとめます。
なお、環境はubuntu11.10、かつすでに以前にインストール済みのruby等はいろいろやっていくうちに、正常箇所とぶっ飛ばした箇所が訳がわからないことになっていったので、一旦ruby周りを出来る限り消した後、1.9系列のみを入れなおすように行なっています。

sudo apt-get install libxml2-dev libxslt1-dev ruby1.9.1-full
sudo gem install rubygems-update
sudo update_rubygems
sudo gem install nokogiri

手順としては、最初にruby1.9および、nokogiriに必要なライブラリの導入、その後gemのアップデート用のツールのインストール→アップデート、nokogiriのインストールを行なっています。

ライトノベル一覧の取得

次にライトノベルの一覧を取得する方法を模索しました。

http://hiki.cre.jp/write/?LightNovelListのような一覧もありましたが、非公式な一覧なため載っていない作品も多く、また公的な書籍一覧等を探す方法を考えましたが、その中からライトノベルだけを抜き出す方法が思い浮かばず、断念しました。

最終的に、Wikipediaのライトノベル(レーベル別)のページからレーベル毎のカテゴリページURLを取得、更にそのページからタイトルを取得して、そこから解析する方法を行いました。

最終的なソースコード

そして、最終的に作成を行ったコードは以下のようになりました。
さすがに、”魔王”だけしか調べられないのも汎用性が低すぎるので、コマンドライン引数から文字列を受け取ってその文字列を含むタイトルを検索するようにしました。(どっちにしろ汎用性なんてまったくないようなものですが…)

#!/usr/bin/env ruby
# -*- coding:utf-8 -*-
require 'open-uri'
require 'nokogiri'

#コマンドライン引数が空の場合、"魔王"で検索
if ARGV[0].nil? then
ARGV[0]="魔王"
end

# urlを指定する
url = 'http://ja.wikipedia.org/wiki/Category:%E3%83%A9%E3%82%A4%E3%83%88%E3%83%8E%E3%83%99%E3%83%AB_(%E3%83%AC%E3%83%BC%E3%83%99%E3%83%AB%E5%88%A5)'
# IE8のフリをする
user_agent = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'

doc = Nokogiri::HTML( open(url, 'User-Agent' => user_agent).read )

count=0
doc.xpath('//div[starts-with(@id, "mw-subcategories")]').map do |elm|
  elm.xpath('.//a/attribute::href').map do |uri|
    doc2 = Nokogiri::HTML( open("http://ja.wikipedia.org"+uri, 'User-Agent' => user_agent).read )
    doc2.xpath('//div[starts-with(@id, "mw-pages")]').map do |elm2|
      elm2.xpath('.//a/attribute::title').map do |title|
        if title.content.include?(ARGV[0])
          puts  title
          count+=1
        end
      end
    end
  end
end
puts "\""+ ARGV[0]+"\"を含むタイトル名 合計:" + count.to_s

正直な話、作っている途中から結構詰まった上に、Wikipedia上でも追加されていないタイトル等もいくつもあるため、この方法では完全なリスト作成およびカウントはできないことは確定的でした。
しかし、HTML解析の練習も兼ねてやっていたので、とりあえず動いて一覧表示+個数カウントぐらいは完成させました。

やっている途中で目的と手段が入れ替わるいい例です。

ちなみに今現在(2012/03/10)このコードを実行した際の結果は以下のとおりです。

$ ruby maou.rb
魔王と踊れ! 〜Legend of the Lord of Lords〜
いちばんうしろの大魔王
魔王学校に俺だけ勇者!?
かぐや魔王式!
魔王っぽいの!
俺と彼女が魔王と勇者で生徒会長
クリス・クロス 混沌の魔王
魔王様げ〜む!
"魔王"を含むタイトル名 合計:8

$ ruby maou.rb 勇者
くじびき勇者さま
魔王学校に俺だけ勇者!?
勇者王ガオガイガーFINAL
伝説の勇者ダ・ガーン
俺と彼女が魔王と勇者で生徒会長
伝説の勇者の伝説
勇者になれなかった俺はしぶしぶ就職を決意しました。
"勇者"を含むタイトル名 合計:7

参考リンク


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください