勉強もかねて、楽天高速バスサービスをPHPでスクレイピングしてみたメモ。
https://github.com/kuredev/rakuten_scraping
作ったもの
楽天高速バスサービスから、指定の経路の、
* 最安値バスの金額とコース名
* 予約可能な件数
を取得してMySQLに保存する。
cronで回してデータを取りつづければ、最安値の推移等を分析できる。
スクレイピング部分
例として
・2014年9月12日
・東京→大阪の夜行バス
・3列シート
を条件に「予約可能件数」、「最安値」、「最安値のコース名」を配列として取得する処理を書いてみます。ライブラリとして、「simple_html_dom」を使います。
流れとしては、
①ソースの取得
②必要なデータが記述されたタグを特定
③特定のタグを指定し、データを抽出
④PHPのデータ構造に格納する
となります。まずスクリプトを示します。
require_once dirname(__FILE__).'/lib/simple_html_dom.php';
function get_bus_info(){
//①
$url = 'http://bus.travel.rakuten.co.jp/bus/ReSearchOpenSeatAction.do?f_rsf=&f_chd=0&f_cthr=true&f_cfou=false&f_fst=&f_sky=price&f_tst=&f_dsctcd=ALL&f_prcsq=0&f_isb=false&f_adt=1&f_cwom=false&f_ctwo=false&f_spy=&f_dscpcd=osaka&f_crel=false&f_cnig=true&f_stm=09&f_ctts=false&f_sk=0&f_spm=&f_sty=2014&f_dpcpcd=tokyo&f_spd=&f_cday=false&f_spc=&f_dpctcd=ALL&f_gyt=&f_cres=false&f_rno=&f_std=12';
$html = file_get_html($url);
//②、③
$kensu = $html->find(".paging_str", 0)->plaintext;
$course_name = str_replace(array("\r\n","\r","\n"), '', trim($html->find(".result_route",0)->plaintext));
$price = parsePrice($html->find(".result_price", 0)->plaintext);
//③
return array(
"kensu" => $kensu,
"price" => $price,
"course_name"=>$course_name
);
}
肝は②、③ですが、タグを特定するには、Chromeの「要素の検証」を実施すると簡単に分かります。スクレイピングしたいページを開いて特定の部分をマウスで選択し、右クリックすると選択出来ます。
タグさえ分かれば、simple_html_domを使うとデータの抽出も②の方法で簡単に出来ることが分かると思います。
楽天高速バスの場合は、上記URL中のresult_priceクラスの一番最初に取れるものが最安値となっているわけです。
DBへの保存
今回は単一のテーブルに保存するだけなので、特に工夫することもないのですが、ORMライブラリとして、php-activerecordを使ってみました。以下のようにほとんどコードを書くことなく、DBに保存出来ました。
$arr = get_bus_info($url);
Week::create($arr);
class Week extends ActiveRecord\Model{
static $table_name = 'weeks';
static $primary_key = 'week_id';
}
分析結果
調べてみると面白かったので、たまにはブログに書いてみました。
楽天高速バス予約ページを分析して分かった最適な高速バス予約のタイミングと金額について - ざっき http://kure.hatenablog.jp/entry/2014/09/11/230916