すやすや生活日記

専業主婦が日々を記録するブログ

【Python】楽天トラベルAPIで空き室検索 ~1~

 

楽天トラベルAPIの空き室検索を使って、好きな旅館を空き室検索するPythonプログラム、作りました。

 

楽天トラベルAPIを使うための準備

楽天トラベルAPIを利用するには、お持ちの楽天アカウント(無い人は作成)で

Rakuten Web Serviceにログインし、アプリIDを取得する必要がある。

ネットを探すと色々な人が解説しているのでご参照ください。

 

楽天トラベル空き室検索APIを使ってみる

まずは単純に以下の検索条件で空き室を検索してみる。

 

ホテル名:星野リゾート リゾナー小浜島
ホテル番号:178403
チェックイン日:2023年6月24日
チェックアウト日:2023年6月25日
人数:大人2名
条件:禁煙、朝食付き
ソート:金額が安い順
 

「ホテル番号」は、各ホテルに割り当てられた一意の番号。

楽天トラベルのホテルのTOPページに飛んでもらい、URLのこの部分↓を抜き出せばOK(楽天トラベル施設検索APIを使っても取得できるが、面倒くさいので…)

星野リゾート リゾナーレ小浜島<小浜島> 宿泊予約【楽天トラベル】 (rakuten.co.jp)

 

code

import requests
import json
import time

def search():
    REQUEST_URL = "https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426"
    APP_ID = "自分のアプリID"
    hotelNum="178403"
    checkinDate="2023-06-24"
    checkoutDate="2023-06-25"
    condition="kinen,breakfast"
    
    
    params = {
        "format":"json",
        "applicationId":APP_ID,
        "hotelNo":hotelNum,
        "checkinDate":checkinDate,
        "checkoutDate":checkoutDate,
        "adultNum":2,
        "squeezeCondition":condition,
        "sort":"+roomCharge"
    }
    response = requests.get(REQUEST_URL, params)
    time.sleep(1)
    res = json.loads(response.text)
    print(res)


if __name__ == '__main__':
    search()

 

APP_ID = "自分のアプリID"

"自分のアプリID"の部分には、あらかじめ取得しておいた楽天APIのアプリIDを入れる。

 

実行結果

 

Oh.....ごちゃごちゃ(;´・ω・)

JSON形式でデータが返ってくるのだけれど、私の使っている開発環境(Jupyter Notebook)は整列してくれないので見づらい。

 

Notepad++を使ってJSONデータを整形してみると以下になった。

 

実行結果

{
    'pagingInfo': {
        'recordCount': 1,
        'pageCount': 1,
        'page': 1,
        'first': 1,
        'last': 1
    },
    'hotels': [{
            'hotel': [{
                    'hotelBasicInfo': {
                        'hotelNo': 178403,
                        'hotelName': '星野リゾート\u3000リゾナーレ小浜島<小浜島>',
                        'hotelInformationUrl': 'https://img.travel.rakuten.co.jp/image/tr/api/re/pvonD/?f_no=178403',
                        'planListUrl': 'https://img.travel.rakuten.co.jp/image/tr/api/re/vFumt/?f_no=178403&f_flg=PLAN',
                        'dpPlanListUrl': 'https://img.travel.rakuten.co.jp/image/tr/api/re/WzozX/?noTomariHotel=178403',
                        'reviewUrl': 'https://img.travel.rakuten.co.jp/image/tr/api/re/gJNfM/?f_hotel_no=178403',
                        'hotelKanaName': 'ほしのりぞーと\u3000りぞなーれこはまじま',
                        'hotelSpecial': '石垣島から25分。世界有数の珊瑚の海が広がる、沖縄離島のプライベートビーチリゾート。',
                        'hotelMinCharge': 20000,
                        'latitude': 87583.57,
                        'longitude': 446393.82,
                        'postalCode': '907-1221',
                        'address1': '沖縄県',
                        'address2': '八重山郡竹富町小浜2954',
                        'telephoneNo': '050-3134-8093',
                        'faxNo': '000-000-0000',
                        'access': '石垣空港',
                        'parkingInformation': '有り\u300020台\u3000無料\u3000予約不要',
                        'nearestStation': '石垣空港',
                        'hotelImageUrl': 'https://img.travel.rakuten.co.jp/share/HOTEL/178403/178403.jpg',
                        'hotelThumbnailUrl': 'https://img.travel.rakuten.co.jp/HIMG/90/178403.jpg',
                        'roomImageUrl': 'https://img.travel.rakuten.co.jp/share/HOTEL/178403/178403_kan1.jpg',
                        'roomThumbnailUrl': 'https://img.travel.rakuten.co.jp/HIMG/INTERIOR/178403.jpg',
                        'hotelMapImageUrl': 'https://img.travel.rakuten.co.jp/share/HOTEL/178403/178403map.gif',
                        'reviewCount': 81,
                        'reviewAverage': 4.57,
                        'userReview': 'スタッフ全員の接客態度には非常に好感が持てて、さりげない語りかけとおもてなしは好印…\u30002023-05-17 01:17:15投稿 つづきはこちら'
                    }
                }, {
                    'roomInfo': [{
                            'roomBasicInfo': {
                                'roomClass': 'ss4',
                                'roomName': 'スーペリアスイート',
                                'planId': 5566607,
                                'planName': '特別優待プラン<朝食付>',
                                'pointRate': 1,
                                'withDinnerFlag': 0,
                                'dinnerSelectFlag': 0,
                                'withBreakfastFlag': 1,
                                'breakfastSelectFlag': 0,
                                'payment': '2',
                                'reserveUrl': 'https://img.travel.rakuten.co.jp/image/tr/api/re/IdsCY/?f_no=178403&f_syu=ss4&f_hi1=2023-06-24&f_hi2=2023-06-25&f_heya_su=1&f_otona_su=2&f_s1=0&f_s2=0&f_y1=0&f_y2=0&f_y3=0&f_y4=0&f_camp_id=5566607',
                                'salesformFlag': 0
                            }
                        }, {
                            'dailyCharge': {
                                'stayDate': '2023-06-24',
                                'rakutenCharge': 39150,
                                'total': 78300,
                                'chargeFlag': 0
                            }
                        }
                    ]
                    ~~~~~~以下略~~~~~~
                    

 

ちょっとは見やすくなったかな(^^;)

このJSONデータから、欲しい情報だけをピックアップするコードを追加する。

 

code

hotelName=res["hotels"][0]["hotel"][0]["hotelBasicInfo"]["hotelName"]
roomName=res["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["roomName"]
planName=res["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["planName"]
stayDate=res["hotels"][0]["hotel"][1]["roomInfo"][1]["dailyCharge"]["stayDate"]
totalCrg=res["hotels"][0]["hotel"][1]["roomInfo"][1]["dailyCharge"]["total"]
planUrl=res["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["reserveUrl"]
allplanUrl=res["hotels"][0]["hotel"][0]["hotelBasicInfo"]["planListUrl"]

txt=""
txt = txt + '\r\n' \
+ "宿名: " + hotelName + '\r\n' \
+ "部屋名: " + roomName + '\r\n' \
+ "プラン名: " + planName + '\r\n' \
+ "宿泊日: " + stayDate + '\r\n' \
+ "価格: " + str(totalCrg) + "円" + '\r\n' \
+ "予約ページURL: " + planUrl + '\r\n' \
+ "プラン一覧URL: " + allplanUrl
        
print(txt)

 

実行結果

宿名: 星野リゾート リゾナーレ小浜島<小浜島>
部屋名: スーペリアスイート
プラン名: 特別優待プラン<朝食付>
宿泊日: 2023-06-24
価格: 78300円
予約ページURL: https://img.travel.rakuten.co.jp/image/tr/api/re/IdsCY/?f_no=178403&f_syu=ss4&f_hi1=2023-06-24&f_hi2=2023-06-25&f_heya_su=1&f_otona_su=2&f_s1=0&f_s2=0&f_y1=0&f_y2=0&f_y3=0&f_y4=0&f_camp_id=5566607
プラン一覧URL: https://img.travel.rakuten.co.jp/image/tr/api/re/vFumt/?f_no=178403&f_flg=PLAN

 

JSON形式のデータの見方は、初心者にはなかなか辛いものがあったけれど、なんとか抜き出せた。。。

 

最後に今日作ったソースコードと、スクレイピングの勉強に使用した書籍を貼り付けておきます。

 

code

import requests
import json
import time

def search():
    REQUEST_URL = "https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426"
    APP_ID = "自分のアプリID"
    hotelNum="178403"
    checkinDate="2023-06-24"
    checkoutDate="2023-06-25"
    condition="kinen,breakfast"
    
    
    params = {
        "format":"json",
        "applicationId":APP_ID,
        "hotelNo":hotelNum,
        "checkinDate":checkinDate,
        "checkoutDate":checkoutDate,
        "adultNum":2,
        "squeezeCondition":condition,
        "sort":"+roomCharge"
    }
    response = requests.get(REQUEST_URL, params)
    time.sleep(1)
    res = json.loads(response.text)
    
    hotelName=res["hotels"][0]["hotel"][0]["hotelBasicInfo"]["hotelName"]
    roomName=res["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["roomName"]
    planName=res["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["planName"]
    stayDate=res["hotels"][0]["hotel"][1]["roomInfo"][1]["dailyCharge"]["stayDate"]
    totalCrg=res["hotels"][0]["hotel"][1]["roomInfo"][1]["dailyCharge"]["total"]
    planUrl=res["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["reserveUrl"]
    allplanUrl=res["hotels"][0]["hotel"][0]["hotelBasicInfo"]["planListUrl"]

    txt=""
    txt = txt + '\r\n' \
    + "宿名: " + hotelName + '\r\n' \
    + "部屋名: " + roomName + '\r\n' \
    + "プラン名: " + planName + '\r\n' \
    + "宿泊日: " + stayDate + '\r\n' \
    + "価格: " + str(totalCrg) + "円" + '\r\n' \
    + "予約ページURL: " + planUrl + '\r\n' \
    + "プラン一覧URL: " + allplanUrl
        
    print(txt)


if __name__ == '__main__':
    search()