今までちょっとしたスクレイピングはPHPで済ましていましたが、最近はAjaxで要素をロードするサイトも多く、PHPだけでスクレイピングを行うのは少々困難になってきました。
もっと柔軟で効率の良いスクレイピング方法はないものかと色々調べてみたところ、「どうやらスクレイピングにはRubyが適している」ということが分かりました。
Rubyには以前から興味があったものの、なかなか必要に迫られることもなくスルーしていましたが、良い機会なので少し勉強してみることにしました。
Ruby(ルビー)は、まつもとゆきひろ(通称 Matz)により開発されたオブジェクト指向スクリプト言語であり、スクリプト言語が用いられてきた領域でのオブジェクト指向プログラミングを実現する。 また日本で開発されたプログラミング言語としては始めて国際電気標準会議で国際規格に認証された事例となった。
ウィキペディア(Wikipedia)
クローラーを作りたかったこともあり、早速『Rubyによるクローラー開発技法』という本を購入。この本の売りである「運用例」はAPIを利用した例が多く、自分にはあまり成果がありませんでしたが、序盤〜中盤でのクロールとスクレイピングに必要なライブラリについての解説は比較的丁寧だったこともあり、Ruby未経験の私でも、基本ノウハウを得ることが出来ました。
で、実際にRubyを触ってみた感想ですが、すごく良いです。
流石、“エレガントなプログラミング言語”と言われるだけあり、行末のセミコロンや条件分岐の{}が不必要だったりと、とても見やすく、より短いスクリプトでコーディングが可能です。
例えば、100回繰り返す処理をPHPで書くと
1 2 3 4 5 |
<?php for($i=0;$i<100;$i++){ //処理 } ?> |
となりますが、Rubyだと…
1 2 3 |
100.times do #処理 end |
実にシンプルです。
Rubyの強みは正規表現処理にあると思いますが、便利なライブラリの数々も標準で用意されており、PHPでは面倒だった“スクレイプ→パース→XML出力→外部サーバーにFTPアップロード”という工程もRubyならサクっと書くことができ、常に人気プログラミング言語ランキングの上位にいるのも納得できます。
残念ながら、RubyはPHPのようにHTML内に簡単にプログラムを組み込めないため、一般的なWEBサイトの制作においてはなかなか使い道がないのですが、上記の工程のように、バックグラウンドで行うデータの収集・解析・作成には十分活躍できそうなので、今後は部分的にでも積極的にRubyを導入していきたいと思います。
最後に、スクレイピングとは関係ありませんが、Twitter APIを使った“自動フォロー返し”をRubyで作ってみたので載せておきます。
1 |
gem install twitter |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
require 'twitter' USERNAME = 'XXXXXXXXXX' CONSUMER_KEY = 'XXXXXXXXXX' CONSUMER_SECRET = 'XXXXXXXXXX' ACCESS_TOKEN = 'XXXXXXXXXX' ACCESS_TOKEN_SECRET = 'XXXXXXXXXX' client = Twitter::REST::Client.new( :consumer_key => CONSUMER_KEY, :consumer_secret => CONSUMER_SECRET, :access_token => ACCESS_TOKEN, :access_token_secret => ACCESS_TOKEN_SECRET ) followers = [] client.follower_ids(USERNAME).each do |id| followers.push(id) end friends = [] client.friend_ids(USERNAME).each do |id| friends.push(id) end client.follow(followers - friends) |
ちなみに同じことをPHPで書くとこうなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php require_once 'twitteroauth/twitteroauth.php'; $consumer_key = "XXXXXXXXXX"; $consumer_secret = "XXXXXXXXXX"; $access_token = "XXXXXXXXXX"; $access_token_secret = "XXXXXXXXXX"; $to = new TwitterOAuth( $consumer_key, $consumer_secret, $access_token, $access_token_secret ); $followers = $to->get('followers/ids', array('cursor' => -1)); $friends = $to->get('friends/ids', array('cursor' => -1)); foreach ( $followers->ids as $i => $id) { if (empty($friends->ids) or !in_array($id, $friends->ids)) { $req = $to->post('friendships/create', array('user_id' => $id)); } } ?> |