2012/11/16

[ruby]Mechanize+nokogiriでスクレイピング体験

ひっさびさにruby書いたら、if文の書き方をど忘れして(endという単語をど忘れ)、少し凹み気味ですが、nokogiriでスクレイピングする事があったので、簡単にまとめておきます。



nokogiri単品でURLからデータを拾ってきてパースする事もできますが、今回はログイン認証を通過した先のデータをスクレイピングしたかったので、Mechanizeとセットで利用しました。

#! /usr/bin/ruby -Ke
# rubyのパスは "which ruby" で各自調べてください

require "rubygems"
require "mechanize"

agent = Mechanize.new  # 通らなかったら WWW::Mechanize.new で試して
agent.user_agent = "好きなユーザーエージェントをここにコピペ"
agent.max_history = 1  # ページの履歴が必要な場合は適宜上げる。 0にするとたまに困るので1にしておく


事前準備はだいたいこんな感じで。
認証をしっかりやってるサイトは、フォームにトークンをこっそりセットしている事があるので、botだからといっていきなりズドンとURLを狙い撃ちせず、人間がアクセスするページ遷移を思い描きながらページを辿って行くとすんなり行くでしょう。

実はMechanizeを使う前にターミナル上でcurlを使って実装しようとしましたが、うまく行きませんでした。
しかしMechanizeを使ったら5分後にはログイン突破してました。セッションやクッキーみたいな表には現れない情報もブラウザと同じ挙動にしているようですね。使いやすい。
まだまだcurl仙人への道は遠いなぁ。

別に隠す事もないと思うので言いますが、ムームードメインのログインを突破しようと思ってたんですね。あ、もちろん自分のアカウントですよ。
page = agent.get("https://muumuu-domain.com/......ムームードメインのログイン画面"


これで、pageの中にパース済のオブジェクトが入ります。
JavaScript(jQueryなど)をよく使う人は、CSSセレクタで要素の選択ができるので簡単に使えます。
tbl = page.root.css(".TBL4")


HTMLタグによる抽出も簡単。
tr = tbl.search("tr")


複数の要素が入るので、trは配列です。なので
tr.shift
tr.each{|row|
  # ごにょごにょこねくり回す
}

こんな風に書くこともできます。
と簡単にスクレイピングできるわけですね。
1ページ分の処理が終わったら、少しだけインターバルを置いてから次の処理に移ります。
page = agent.get("......")
text = page.root.search("div#header")
# 色々処理する
sleep 5     # 5秒スリープ

例の図書館の事件もありますからね。最近、鼠と竜のゲームという連載が始まって、この手の技術について慎重にならざるを得ないような気持ちに駆られた、事件当時を思い出すとヒヤリとしますね。

nokogiriは、xpathによる抽出にも対応していますが、今回触っていないので、紹介しているサイトを紹介しておきます。
Nokogiri
公式ページ。全クラス・全メソッドの羅列なので、ある程度わかってないとキツイ
[Ruby]スクレイピングのためのNokogiri利用メモ
非常に簡潔。だいたいまとまっています。
Rubyで簡単Web解析|NokogiriでHTML XMLパーサー
Mechanizeを使わないでnokogiriしてます。formとか弄う必要なければこれで十分


おまけ・nokogiri+Mechanizeの導入で詰まってる・・・

世の中って便利なもんで、両方共rubygemsで一発インストール・・・のはずなんですが、まぁたまにはできないこともあるようです。
だいたいは「libxslt」か「libxml2」のどちらかがないという事なので、apt-getしてしまいます。
どっちがないかはログにありますが、既にインストール済ならスキップされるのでそっとコピペでおk。
sudo apt-get install libxslt-dev libxml2-dev rubygems
sudo gem install nokogiri mechanize

以上で導入は完了。


0 件のコメント:

コメントを投稿