Fire Engine

化学の修士号→消防士→ITエンジニア(2016年11月〜)

Rubyで始めるクローラー開発とスクレイピング & 為替情報を取得してみる。

 近年「ビッグデータ」 という言葉が急速に流行し、 注目を集めています。ビッグデータとは、そのまま解釈すると膨大なデータのことですが、インターネット上の私たちの行動履歴もビックデータの重要な一部となっています。例えば、Googleでキーワードを検索する、Webページにアクセスする、アクセス先で商品を購入する、FacebookTwitterに書き込むなど、近年のインターネット社会では日々あらゆる履歴が蓄積されています。このような流れは、更なるインターネットの普及やIT技術の発展により、今後も加速していくことが容易に予想され、ビジネス界においては、蓄積されたデータをどのように活用していくかが成功のカギとなることは間違いないでしょう。

 一言に「データの活用」と言っても、そこにはいくつかのプロセスが存在します。データを集める→集めたデータを分析する→有益な情報を抜き出す→得られた結果をフィードバックする、などのプロセスです。今回は、このプロセスの中でも最初の一歩となる『データを集める』についてのお話です。データを集める際に、人間が手作業で集めていたのでは、時間もかかるし効率が悪いですよね?それをコンピュータに行わせることができたらとても便利ですし、そもそも人間に比べてはるかに処理能力が高いコンピュータを用いることで、データの収集効率も飛躍的に向上させることができます。今回の記事では、クローラー開発の概要や基本的な知識について書き、最後に非常に簡単なクローラを使って、Yahoo!ファイナンスから為替情報を取得してみます。

今回の目次はこんな感じです。

目次

クローラースクレイピング

 データ収集において、非常に重要なキーワードとして「クローラー」と「スクレイピング」が挙げられます。クローラーとは、システムが自動的にWebページを巡回して情報(文章や画像など)を収集するプログラムのことです。スクレイピングとは、収集したデータから特定のデータを抽出する技術・行為のことです。

 クローラーの構造は大きく3つの機能に分類できます。

①コンテンツの取得(クローリング)

②データの抽出(スクレイピング

③データの保存

したがって、スクレイピングクローラーの機能の一つとなります。

Rubyによるクローラー開発

 Rubyは国産のオブジェクト指向スクリプト言語として、今や世界で広く使われていますが、Rubyクローラー開発にもとても適しています。その理由の一つが、クローラー開発に利用できるライブラリが充実していることです。ここでは、代表的なライブラリを3つ紹介します。

・open-uri

 Rubyのダウンロードライブラリの定番です。Rubyにはファイルを開くための組み込みメソッドとして、openメソッドというものがあります。openメソッドは通常、ファイル名を引数に取りますが、open-uriにより引数にURLを指定できるようになります。そうすることで、ごく普通のRubyスクリプトで簡単にHTTPアクセスが行えるようになります。open-uriは標準添付ライブラリであるため、Rubyが利用可能であればすぐに使うことができます。

library open-uri (Ruby 2.1.0)

・Nokogiri

 NokogiriはRubyスクレイピングする際によく使われるライブラリです。HTMLやXMLの構造を解析でき、特定の要素を指定して取り出すことができます。このようなものをHTML・XMLパーサーと呼びます。Nokogiriの特徴は、XPathCSSセレクタを使って要素を抽出できる機能を持つことです。使い方は、下記のチュートリアルを見るのが一番いいと思います。

www.nokogiri.org

・Anemone

 Ruby製のクローラーフレームワークです。クローラーが必要とするデータの取得、解析、保存のすべての機能を備えている優れものです。下記のリンクでGitHubを見てみると2012年頃に開発が停止しているようですが、現在でも広く利用されているようです。

GitHub - chriskite/anemone: Anemone web-spider framework

クローラーは何かと注意が必要である。

 クローラーは短時間にサイトに大量のリクエストを送るため、悪用すればサイトへの攻撃にもなり得ます。また、クローリングの対象となるWebサイトは著作物であるため、著作権に関しても留意しておく必要があります。クローラー開発における注意事項については下記の記事にまとまっているので、参考にして下さい。

qiita.com

qiita.com

そもそもクローラーを作る必要があるのかをまず考える。

 どういうことかというと、「クローラーはできる限り作らない方がよい。」ということです。前述のように何かと注意が必要であるクローラーは、他の方法で目的を達することができるなら、なるべく避けたほうがよいみたいです。何かしらデータを収集したい場合は、まず以下のことを考慮するとよいと思います。

APIの活用ができないかを検討する。

 AmazonFacebookTwitterなど大手サイトの多くはAPIを提供しており、APIを利用することで目的のデータを取得できるケースが増えています。APIで目的が達成できる場合は、APIを積極的に利用したほうがよいでしょう。

 クローリングの対象サイトがAPIを提供していない場合や、APIではどうしても取得できないデータを集めたいときに初めてクローラーの作成を検討します。APIについては以下の記事がまとまっています。

qiita.com

APIではどうしても取得できないデータを集めたい」ということはけっこう出てくると思います。例えば、Amazonでは、ランキングやセール情報などはAPIでは取得できないようです。

RSSの利用ができないか検討する。

 RSSとはWebサイトの見出しや要約などのメタデータを構造化して記述するXMLベースのフォーマットのことです。Amazonではページの下の方にRSSフィードへのリンクがあります。

f:id:hirotsuru314:20160626212744p:plain

 RSSフィードXML形式で記述されているため、コンピュータが理解しやすく、プログラムから取得や解釈が容易であるという特徴があります。したがって、クローラーを作成する際はできるだけRSSを利用する方が、より簡単かつ効率よくデータの収集ができます。また、サイト運営側としても、クローラーがHTMLページを巡回するよりも、RSSフィードからデータを取得される方が負荷が少なく好ましいようです。

(補足)

wgetコマンドというものがあり、これを使うと、UNIXコマンドラインで HTTP や FTP 経由のファイル取得を行えます。やりたいことがWgetのみで完結する場合は、わざわざRubyクローラーを開発する必要はなく、クローリングをWgetに任せるのも一つの方法です。

http://girigiribauer.com/archives/925girigiribauer.com

Yahoo!ファイナンスから為替情報を取得する。

Yahoo!ファイナンスhttp://info.finance.yahoo.co.jp/fx/detail/?code=USDJPY=FX)から米ドル/円のBid(売値)とAsk(買値)を取得してみます。

f:id:hirotsuru314:20160626212748p:plain

 取得にはNokogiriを使います。(Nokogiriは事前にインストールする必要があります。)以下にコードを示します。

require 'nokogiri'
require 'open-uri'

url = 'http://info.finance.yahoo.co.jp/fx/detail/?code=USDJPY=FX'
doc = Nokogiri::HTML(open(url))
bid = doc.xpath("//*[@id='USDJPY_detail_bid']").text
ask = doc.xpath("//*[@id='USDJPY_detail_ask']").text
puts "Bid(売値):#{bid}"
puts "Ask(買値):#{ask}"

これをターミナルで実行すると

Bid(売値):102.313
Ask(買値):102.317

という結果が出てきて、上のWebページと同じ値が返ってきます。このようにNokogiriを使えば10行足らずのコードでデータを取得したりできます。

 コードを上から見ていくと、まずは必要となるライブラリの読み込み。次に、対象となるWebページのURLを変数urlに格納する。docの部分では、open-uriライブラリを読み込んでいるため、openメソッドに直接URLを渡せます。

 次にXPathを指定して、取り出す要素を決めています。XPathについては以下の記事が参考になります。

1.XPath の基本 1 | TECHSCORE(テックスコア)

 要は、HTMLソースコードを観察し、タグを階層的に指定するわけです。Google Chromeでは、ページで右クリックし、「検証」をクリックすると下図の右のように、HTMLソースコードが出てきます。そこで、取得したい要素を階層的にたどっていき、見つけたらまた右クリックして「Copy」→「Copy XPath」でXPathをコピーできます。

f:id:hirotsuru314:20160626212753p:plain

 最後のputsは出力の部分です。どうでしょうか?これを応用するといろいろできそうですよね?

 気づいたかも知れませんが、今回のものはクローリングの部分が機能していません。今回は目的のページが一つに決まっていて、ページ指定のクローラーを作りました。一方、クローラーとしての本領を発揮するのは、不特定のページから条件にあてはある情報を抜き出すようなケースだと思います。この場合は巡回のルールを自分で決めていくわけですが、先に紹介したAnemoneを使うと、巡回機能も比較的簡単に実装できるので、興味がある方は試してみてください。私も今後より高度なクローラを開発し、また記事に書きたいと思います。

今後やりたいこと

・Crondなどを使ってクローラーを自動化してみたい。

クローラーをWebアプリ化して、取得した情報をブラウザを介して見れるようにしたい。

・官公庁のオープンデータを使ってデータ分析をしてみたい。

参考書

 クローラー開発に必要なことはすべて下記の本から学びました。私のような初心者でもスクレイピングなどの比較的高度なタスクが行えるようになり、本当に楽しく勉強させてもらいましたし、とてもワクワクしました。本当に最高の本だと思います。よければ読んでみてください。(本の内容を理解するためには多少のRubyの基礎知識が必要です。)

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

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