(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【楽天トラベル】特定のホテルの料金をcurlコマンドで自動的に取得する

スポンサーリンク

はじめに

楽天トラベルにてとあるホテル料金をブラウザで検索していた際、URLにて入力情報を管理している仕組みに気づいたのでcurlコマンドで日付をずらしながら料金を取得するスクリプトを作ってみました。本記事ではその備忘録です。

利用コマンド
$ curl --version
curl 7.52.1 (x86_64-pc-linux-gnu) libcurl/7.52.1 OpenSSL/1.0.2u zlib/1.2.8 libidn2/0.16 libpsl/0.17.0 (+libidn2/0.16) libssh2/1.7.0 nghttp2/1.18.1 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL

楽天トラベルのURL体系

例えば群馬県の水上山荘というホテルを4/1~4/2の一泊二日で男性一人で検索するとURLは以下となります。

https://search.travel.rakuten.co.jp/ds/vacant/searchVacant?f_chu=gunma&f_shou=numata&f_sai=&f_hi1=1&f_tuki1=4&f_nen1=2020&f_hi2=2&f_tuki2=4&f_nen2=2020&f_no=134873&f_kin=&f_kin2=0&f_tab=plan&f_sort=kin&f_heya_su=1&f_otona_su=1&f_s1=0&f_s2=0&f_y1=0&f_y2=0&f_y3=0&f_y4=0&f_kaiin_no=&f_kaiin_tel=&f_jyoken=no&f_cd=03&f_dai=japan&f_image=1&f_page=1&f_hyoji=30&ref=info

検索結果は以下のようにブラウザ上に表示されます。

f:id:mtiit:20200308111929p:plain
楽天トラベルの検索結果画面

ここでポイントはURLの

f_hi1

にチェックイン日

f_hi2

にチェックアウト日が入っています。

楽天トラベルのHTML体系

HTMLを表示すると以下のように検索結果がJSON形式で格納されています。

 var ds = {"actionPath":"searchVacant","areaName":"水上・猿ヶ京・沼田","conditions":{"f_no":["134873"],"f_sort":["hotel_kin_low"],"f_campaign":[""],"f_point_min":["0"],"f_page":["1"],"seo_f_chu":[""],"seo_f_shou":[""],"f_gcode":[""],"f_cd":["03"],"f_dai":["japan"],"f_chu":["gunma"],"f_shou":["numata"],"f_sai":[""],"f_latitude":["0.0"],"f_longitude":["0.0"],"f_km":[""],"f_squeezes":[],"f_rm_bed":[],"f_rm_type":[],"f_tab":["hotel"],"f_service":null,"f_nen1":["2020"],"f_tuki1":["04"],"f_hi1":["01"],"f_nen2":["2020"],"f_tuki2":["04"],"f_hi2":["02"],"f_otona_su":["1"],"f_s1":["0"],"f_s2":["0"],"f_y1":["0"],"f_y2":["0"],"f_y3":["0"],"f_y4":["0"],"f_heya_su":["1"],"f_kin":[""],"f_kin2":["0"],"f_ido":["0.0"],"f_kdo":["0.0"],"f_teikei":[""],"f_disp_type":[""],"f_hyoji":["30"],"f_image":["1"],"f_setubi":[""]},"displayedHotels":[134873],"facilityName":"谷川温泉 檜の宿 水上山荘","hotels":{"134873":{"plans":{"3327372":{"rooms":{"newb":{"sumTotalChargeTaxExclusive":18000,"sumTotalChargeTaxInclusive":19800,"taxType":"exclusive"}}},"3327371":{"rooms":{"newb":{"sumTotalChargeTaxExclusive":31637,"sumTotalChargeTaxInclusive":34800,"taxType":"exclusive"}}}},"rooms":{}}},"isCamby":false,"isDated":true,"isHotelFixed":true,"isNearbySearch":false,"isSecret":false,"isShowCrossSearch":true,"isSqueezingCambyFlag":false,"narrowingArea":[],"rtcond":{"f_sort":["hotel_kin_low"],"f_campaign":[""],"f_point_min":["0"],"f_gcode":[""],"f_cd":["03"],"f_dai":["japan"],"f_chu":["gunma"],"f_shou":["numata"],"f_sai":[""],"f_latitude":["0.0"],"f_longitude":["0.0"],"f_km":[""],"f_squeezes":[],"f_nen1":["2020"],"f_tuki1":["04"],"f_hi1":["01"],"f_nen2":["2020"],"f_tuki2":["04"],"f_hi2":["02"],"f_otona_su":["1"],"f_s1":["0"],"f_s2":["0"],"f_y1":["0"],"f_y2":["0"],"f_y3":["0"],"f_y4":["0"],"f_heya_su":["1"],"f_kin":[""],"f_kin2":["0"],"f_ido":["0.0"],"f_kdo":["0.0"],"f_teikei":[""],"f_disp_type":[""],"f_page":["1"],"f_hyoji":["30"],"f_image":["1"],"f_setubi":[""]},"rtcondex":{"dated":true,"f_tab":"hotel"},"totalResults":[1]};

料金は以下が税抜き価格として管理されていました。この部分を引っこ抜きます。

"sumTotalChargeTaxExclusive":18000

料金を自動取得するスクリプト

for j in `seq 1 30`
do
jj=`expr $j + 1`
echo -n $j,
curl https://search.travel.rakuten.co.jp/ds/vacant/searchVacant?f_chu=gunma\&f_shou=numata\&f_sai=\&f_hi1=$j\&f_tuki1=4\&f_nen1=2020\&f_hi2=$jj\&f_tuki2=4\&f_nen2=2020\&f_no=134873\&f_kin=\&f_kin2=0\&f_tab=plan\&f_sort=kin\&f_heya_su=1\&f_otona_su=1\&f_s1=0\&f_s2=0\&f_y1=0\&f_y2=0\&f_y3=0\&f_y4=0\&f_kaiin_no=\&f_kaiin_tel=\&f_jyoken=no\&f_cd=03\&f_dai=japan\&f_image=1\&f_page=1\&f_hyoji=30\&ref=info 2>/dev/null| grep sumTotalChargeTaxExclusive | awk '{print substr($0,index($0,"sumTotalChargeTaxExclusive")+28)}' | cut -d"," -f1
done

出力結果は以下です。

./rakuten_travel_test.sh
1,18000
2,18000
3,28000
4,5,19000
6,18000
7,18000
8,18000
9,18000
10,18000
11,12,18000
13,18000
14,18000
15,18000
16,18000
17,18000
18,19,18000
20,18000
21,18000
22,18000
23,18000
24,19000
25,26,18000
27,18000
28,18000
29,28000
30,19000

seq 1 30とすることで4/1から4/30までの一か月分を出力してみました。

終わりに

今回は楽天APIを利用せずにサクッと実装してみました。ヒットしない場合に改行されないなどイケてない箇所もありますが、同様なことを実施したい方は是非参考ください。