Ruby: nokogiri でスクレイビング (Mobage をハッキング)

nokogiri はスクレイビングに便利な gem。HTML をパースして要素を取り出す事ができます。
スクレイビングはアンテナ・キュレーションサイトで広く使用されている制作手法であったり、検索エンジンの情報収集方法なので、ウェブサービスの基本と言えます。

Nokogiri

Mobage を題材にしているのは「ログイン不要で取得可能で、Valid HTMLのためパース可能で、日々変化する情報」だったためです。

Mobage はガラケーを考慮されて作られているため半角カナが混在しています。
今回は NKF モジュールを使用して全角カナに変換しています。
NKF は Ruby 1.8.2 では取り込まれています。

NKF

open-url もデフォルトライブラリです。UserAgent の偽装が可能です。

OpenURL

 

Mobage の現時点でのランキングを取得、標準出力にトレースします。

ruby: mobage_ranking.rb

# encoding: utf-8
require 'open-uri'
require 'nokogiri'
require 'nkf'

def loadRanking(loadUrl, meta)
    charset = nil
    html = open(loadUrl, 'User-Agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53') do |f|
        charset = f.charset
        f.read
    end
    
    p "================================="
    p meta
    doc = Nokogiri::HTML.parse( html, nil, charset )
    
    doc.xpath('//li[@class="line0"]').each do |lineNode|
        p "------"
        lineNode.xpath('.//span[@class="rank"]').each do |node|
            rRank = node.children[1].text
            p rRank
        end
        lineNode.xpath('.//span[@class="caption_l"]').each do |node|
            title = node.children[0].text
            #半角カナを全角カナに置き換え
            rTitle = NKF::nkf('-wm0 ', title)
            p rTitle
        end
        lineNode.xpath('.//span[@class="caption_m"]').each do |node|
            rCaption = node.children[0].text
            #半角カナを全角カナに置き換え
            rCaption = NKF::nkf('-wm0 ', rCaption)
            p rCaption
        end
        lineNode.xpath('.//img[@class="sp-topgame-img"]').each do |node|
            rThumbnail = node.attribute('src').value
            p rThumbnail
        end
    end
end

day = Time.now
p day

# 総合ランキングの取得
loadRanking("http://sp.mbga.jp/_game_ranking?genre=2000&p=1&sex_type=A", "総合 全体 1-10")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=2000&p=2&sex_type=A", "総合 全体 11-30")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=2000&p=1&sex_type=M", "総合 男性 1-10")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=2000&p=2&sex_type=M", "総合 男性 11-30")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=2000&p=1&sex_type=F", "総合 女性 1-10")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=2000&p=2&sex_type=F", "総合 女性 11-30")

# 急上昇ランキングの取得
loadRanking("http://sp.mbga.jp/_game_ranking?genre=1000&p=1&sex_type=A", "急上昇 全体 1-10")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=1000&p=2&sex_type=A", "急上昇 全体 11-30")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=1000&p=1&sex_type=M", "急上昇 男性 1-10")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=1000&p=2&sex_type=M", "急上昇 男性 11-30")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=1000&p=1&sex_type=F", "急上昇 女性 1-10")
loadRanking("http://sp.mbga.jp/_game_ranking?genre=1000&p=2&sex_type=F", "急上昇 女性 11-30")

nokogiri が gem install されている状態で下記を実行。

$ ruby mobage_ranking.rb

実行時点でのランキングが取得されて標準出力に流れる。

続きは github で。