WWW::Mechanize + XPath で快適 Web スクレイピング!

mixi から友人の日記の本文を取得して出力します。

準備。

$KCODE = "e"

require "kconv"

require "rubygems"
require "mechanize"

include WWW

agent = Mechanize.new

とりあえず mixi をゲット。

#Login
page = agent.get("http://www.mixi.jp/")
form = page.forms.first
form["email"] = "mail@address"
form["password"] = "password"
form.submit

#日記一覧ページ
page = agent.get("new_friend_diary.pl")

FirebugXPath を取得します。らくちんだ。

Firebug で簡単に XPath 作れると言っても、まったく意図した通りに動くとは限りません。

そんなときは慌てず、Firebug のコンソール上で

$x('/html/body/div[2]/div/div[2]/ul/li/dl/dd/a[1]')

などとして、XPath のテストをします。

また、はまりやすい点として、Firefox は table 直下に tr がある場合、DOM 上で tbody を補完します。Firebug で取得した XPath には tbody が含まれているので、Mechanize 上では tbody を省いた XPath を使用します。

Xpath が完成したら、Ruby に戻って page.search or page/ に、作成した XPath を渡します。

#FliendDiaryList
fdl = page/"/html/body/div[2]/div/div[2]/ul/li/dl/dd/a[1]"

友人の日記一覧から a タグを収集しました。各リンクをたどって、日記本文を取得し、出力します。

XPath 内でダブルコーテーションを使っている場合はシングルコーテーションで全体をくくろうね。

#GetFriendDiary
fdl.each do |a|
  page = agent.click(a)
  puts (page/'//*[@id="diary_body"]').innerHTML.toutf8.gsub(/<br \/>/, "\n")
  puts "\n--------------------\n\n"
end

ターミナルで実行。

Mechanize ばんざい!