読者です 読者をやめる 読者になる 読者になる

プログラマでありたい

おっさんになっても、プログラマでありつづけたい

Ruby+Nokogiriでスクレイピング入門

クローラー/スクレイピング Advent Calendar 2014の5日目です。あと、全部俺Advent Calendarも開催中です。

f:id:dkfj:20140415021125p:plain

 Webからデータを取るためにスクレイピングする際は、Rubyを使うことが多いです。理由としては、Nokogiriが手軽で簡単だからの一点です。Rubyによるクローラー開発技法でも随所に紹介しています。随所というレベルではなく、手を変え品を変えNokogiriでデータ取っているだけじゃねぇかと批判を受けるのではと、懸念するレベルかもしれません。Nokogiriは手軽で便利なので、ちょっと使い方を覚えておくだけで楽できるケースが一杯あります。ということで、Nokogiri入門編です。

Nokogiriの使い方



 Nokogiriは、Rubyで実装されたHTML/XMLの構文解析器(パーサー)です。Rubyの中では、デファクト・スタンダードと言っても差し支えがないでしょう。XPathやCSSセレクタを利用して、目的の要素を特定し抜き出します。このデータを抜き出すことをスクレイピングと呼びます。Scrape(削る)という意味ですね。
 下記の例は、nokogiriの公式サイトから、ページ中のリンクを全部取得している例です。

scrape.rb

require 'nokogiri' 
require 'open-uri'
doc = Nokogiri.HTML(open("http://nokogiri.org/")) 
doc.css('a').each do |element| 
    puts element[:href]
end

 実行すると次のようになります。

$ ruby scrape.rb 
/
http://rdoc.info/github/sparklemotion/nokogiri
https://github.com/sparklemotion/nokogiri
/tutorials/installing_nokogiri.html
/tutorials/
/tutorials/getting_help.html
/tutorials/installing_nokogiri.html
/tutorials/parsing_an_html_xml_document.html
/tutorials/searching_a_xml_html_document.html
/tutorials/modifying_an_html_xml_document.html
/tutorials/ensuring_well_formed_markup.html
/tutorials/getting_help.html
/tutorials/more_resources.html
//github.com/sparklemotion/nokogiri.org-tutorials
//octopress.org/
//github.com/coogie/oscailte

ソースの解説
 requireで、nokogiriの他にopen-uriというモジュールを呼び出しています。nokogiriはあくまでテキストの文章からデータを抜き出すだけなので、Webからhttp通信でデータを取得することはできません。そこで、open-uriを利用します。open-uriはopenを拡張し、ファイルと同じような形でURLを扱うことが出来ます。
 その習得したHTML文章を、Nokogiri.HTMLで開いて、Nokogiriのドキュメント形式に変換したオブジェクトを作成しています。このオブジェクトはHTMLデータを内包しているので、Nokogiriのメソッドを利用して様々な切り方でデータを取得することができます。

doc.css('a').each do |element| 
    puts element[:href]
end

 この例では、CSSセレクタを利用してaタグのものを全部抜き出しています。それを順次elementという変数に格納しています。そして、elementの中から、href属性の値を取り出して表示しています。Nokogiriには多数のメソッドやエイリアスがありますが、基本的には全てこれと同じことをしています。

  1. 取得する切り口を決定(xpath,cssセレクタ等)
  2. 取得する対象を決定(パス、id、クラス指定等)
  3. 取得したデータに対する操作


検索色々。id指定とclass指定、上位からのタグ指定などがよく使うのではないでしょうか?

#class指定でh2タグを検索
puts doc.xpath("//h2[@class='title']")

#id指定でdivタグを検索
puts doc.xpath("//div[@id='copyright']")

#カスタムの属性値でdivタグを検索
puts doc.xpath("//div[@data-component-term='tweet']")

#id指定で全てのタグを検索
puts doc.xpath("//*[@id='copyright']")

#絞込検索
puts doc.xpath("//div[@id='copyright']//ul")

#上位からのタグ指定
puts doc.xpath("//html/body/article/p[34]")

 かなり簡単な説明でしたが、Nokogriを使ったスクレイピングの入門編です。以前、内部の構造含めてもう少し詳しく説明したエントリーを書いたので、興味があればそちらの方も読んでみてください。色々な言語でスクレイピングしましたが、Nokogiriはかなり使いやすい部類だと思います。それでは、迷惑を掛けない範囲で楽しんでください!!
 あと宣伝になりますが、クローラー/スクレイピングの作り方をこってり解説したRubyによるクローラー開発技法という本も書いています。初心者〜中級者向けですので、興味があれば是非ご覧ください。


See Also:
RubyでWebスクレイピングの話をしてきました。第1回Webスクレイピング勉強会@東京
Ruby製の構文解析ツール、Nokogiriの使い方 with Xpath
あらためてRuby製のクローラー、"anemone"を調べてみた
オープンソースのRubyのWebクローラー"Anemone"を使ってみる

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例