rakuten-travel-crawler 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a05c3df54f9033e816c055b6880a69cfdabca5ab14d01a2c9b34b521ef9dad4
4
- data.tar.gz: 3383a320b501c81901c65fd786d2e84fa3ba12d6d9f45a114c7818689cb70e73
3
+ metadata.gz: 5a68701a3fc477ff0159afc398531837792335cfa7f88e66e3ce66e090d48d7b
4
+ data.tar.gz: ca2e21a91daf0f275c29f84494a1d38e154e88749a27f61e08efcff12318ff46
5
5
  SHA512:
6
- metadata.gz: 35c3892befbbf9887c4087f5987a1f62afa16eb49a677bfe2b20f9487c038a111d2d279546b46bfeb58d86c4a94d42d1c82c63831d050e27336401225a2cbad0
7
- data.tar.gz: 93721fd02b8d8e4c1d53bf46487a84625ee5983acc600519f77765c56b1e5ff34eabba932239ac523d5b211ed53a2bb5cf3ed79586382a1fd7545cb019d00ed6
6
+ metadata.gz: 020b7e8a54913e96f0b22f0bfe4d0a636eb71f5e8978027ed7a6008d6c2d32879444acacd475014c5747f39c2a98a75f71fa3fa008987599bd3f6a4da44674b5
7
+ data.tar.gz: d20dbe4b50fcf657b9253b7cf959c9c8af62588bdc5a5aa8b8b669b4b443694ff48317172a082db3db71c2f4af597c4762845ba1c4765bc2e56f53c621617272
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
-
9
+ .envrc
10
+ .env
10
11
  # rspec failure tracking
11
12
  .rspec_status
@@ -0,0 +1,62 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rakuten-travel-crawler (0.1.0)
5
+ activesupport (~> 6.0.2.2)
6
+ json (~> 2.3.1)
7
+ nokogiri (~> 1.10.9)
8
+ selenium-webdriver (~> 3.141)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ activesupport (6.0.2.2)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ zeitwerk (~> 2.2)
19
+ childprocess (3.0.0)
20
+ concurrent-ruby (1.1.6)
21
+ diff-lcs (1.4.4)
22
+ i18n (1.8.5)
23
+ concurrent-ruby (~> 1.0)
24
+ json (2.3.1)
25
+ mini_portile2 (2.4.0)
26
+ minitest (5.14.1)
27
+ nokogiri (1.10.10)
28
+ mini_portile2 (~> 2.4.0)
29
+ rake (12.3.3)
30
+ rspec (3.9.0)
31
+ rspec-core (~> 3.9.0)
32
+ rspec-expectations (~> 3.9.0)
33
+ rspec-mocks (~> 3.9.0)
34
+ rspec-core (3.9.2)
35
+ rspec-support (~> 3.9.3)
36
+ rspec-expectations (3.9.2)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-mocks (3.9.1)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-support (3.9.3)
43
+ rubyzip (2.3.0)
44
+ selenium-webdriver (3.142.7)
45
+ childprocess (>= 0.5, < 4.0)
46
+ rubyzip (>= 1.2.2)
47
+ thread_safe (0.3.6)
48
+ tzinfo (1.2.7)
49
+ thread_safe (~> 0.1)
50
+ zeitwerk (2.4.0)
51
+
52
+ PLATFORMS
53
+ ruby
54
+
55
+ DEPENDENCIES
56
+ bundler (~> 2.0)
57
+ rake (~> 12.0)
58
+ rakuten-travel-crawler!
59
+ rspec (~> 3.0)
60
+
61
+ BUNDLED WITH
62
+ 2.1.4
data/README.md CHANGED
@@ -28,9 +28,16 @@ TODO: Write usage instructions here
28
28
 
29
29
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
30
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org/gems/rakuten-travel-crawler).
32
32
 
33
33
  ## Contributing
34
34
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rakuten-travel-crawler.
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/elsoul/rakuten-travel-crawler.
36
36
 
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [Apache-2.0 License](https://www.apache.org/licenses/LICENSE-2.0).
40
+
41
+ ## Code of Conduct
42
+
43
+ Everyone interacting in the HotelPrice project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/el-fudo/rakuten-travel-crawler/blob/master/CODE_OF_CONDUCT.md).
@@ -1,10 +1,31 @@
1
1
  require "rakuten/travel/crawler/version"
2
+ require "rakuten/travel/crawler/api"
3
+ require "rakuten/travel/crawler/console"
4
+ require "rakuten/travel/crawler/web"
5
+ require "selenium-webdriver"
6
+ require "net/http"
2
7
 
3
8
  module Rakuten
4
9
  module Travel
5
10
  module Crawler
6
11
  class Error < StandardError; end
7
- # Your code goes here...
12
+
13
+ def self.get_selenium_driver mode: :chrome
14
+ case mode
15
+ when :firefox_remote_capabilities
16
+ firefox_capabilities = Selenium::WebDriver::Remote::Capabilities.firefox
17
+ Selenium::WebDriver.for(:remote, url: "http://hub:4444/wd/hub", desired_capabilities: firefox_capabilities)
18
+ when :firefox
19
+ Selenium::WebDriver.for :firefox
20
+ else
21
+ options = Selenium::WebDriver::Chrome::Options.new
22
+ options.add_argument("--ignore-certificate-errors")
23
+ options.add_argument("--disable-popup-blocking")
24
+ options.add_argument("--disable-translate")
25
+ options.add_argument("-headless")
26
+ Selenium::WebDriver.for :chrome, options: options
27
+ end
28
+ end
8
29
  end
9
30
  end
10
31
  end
@@ -0,0 +1,166 @@
1
+ module Rakuten
2
+ module Travel
3
+ module Crawler
4
+ class Api
5
+ def initialize params
6
+ @config = {
7
+ rakuten_hotel_id: params[:rakuten_hotel_id].to_s ||= 0,
8
+ rakuten_api_key: params[:rakuten_api_key] ||= ENV["RT_API_KEY"]
9
+ }
10
+ end
11
+
12
+ def get_price(rakuten_hotel_id, checkin_date, num_adults)
13
+ query_string = make_query_string(rakuten_hotel_id, checkin_date.to_s, num_adults)
14
+ url = "https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20131024?#{query_string}"
15
+ json = Net::HTTP.get(URI.parse(url))
16
+ result = JSON.parse(json)
17
+ if result["error"] == "not_found"
18
+ {
19
+ date: DateTime.now.strftime("%Y-%m-%d"),
20
+ checkin_date: checkin_date,
21
+ rakuten_hotel_id: @config[:rakuten_hotel_id],
22
+ adult_num: num_adults,
23
+ breakfast: "",
24
+ plan_num: 0,
25
+ min_price: 0
26
+ }
27
+ elsif result["error"] == "wrong_parameterd"
28
+ "入力した値が正しくありません。"
29
+ else
30
+ {
31
+ date: Time.now.strftime("%Y-%m-%d"),
32
+ checkin_date: checkin_date,
33
+ rakuten_hotel_id: rakuten_hotel_id,
34
+ hotel_name: result["hotels"][0]["hotel"][0]["hotelBasicInfo"]["hotelName"],
35
+ adult_num: num_adults,
36
+ breakfast: "",
37
+ plan_num: result["pagingInfo"]["recordCount"],
38
+ room_name: result["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["roomName"],
39
+ plan_name: result["hotels"][0]["hotel"][1]["roomInfo"][0]["roomBasicInfo"]["planName"],
40
+ min_price: result["hotels"][0]["hotel"][1]["roomInfo"][1]["dailyCharge"]["rakutenCharge"]
41
+ }
42
+ end
43
+ end
44
+
45
+ def make_query_string(rakuten_hotel_id, checkin_date, num_adults)
46
+ checkout_date = (Date.parse(checkin_date) + 1).strftime("%Y-%m-%d")
47
+ "format=json&sort=%2BroomCharge&searchPattern=1&applicationId=#{@config[:rakuten_api_key]}&hotelNo=#{rakuten_hotel_id}&adultNum=#{num_adults}&checkinDate=#{checkin_date}&checkoutDate=#{checkout_date}&squeezeCondition="
48
+ end
49
+
50
+
51
+ def hotel_info
52
+ uri = URI.parse("https://app.rakuten.co.jp/services/api/Travel/HotelDetailSearch/20131024?hotelNo=" + @config[:rakuten_hotel_id].to_s + "&applicationId=" + @config[:rakuten_api_key].to_s + "&datumType=1&responseType=large")
53
+ json = Net::HTTP.get(uri)
54
+ result = JSON.parse(json)
55
+ return "ホテル情報がありませんでした。" if result["error"] == "not_found"
56
+ return result["error_description"] if result["error"] == "wrong_parameter"
57
+ result["hotels"][0].each do |_key, field|
58
+ field[0].each do |_, value|
59
+ @data_hash = {
60
+ rakuten_hotel_id: value["hotelNo"],
61
+ hotel_name: value["hotelName"],
62
+ room_price_min: value["hotelMinCharge"],
63
+ lat: value["latitude"],
64
+ lon: value["longitude"],
65
+ tel: value["telephoneNo"],
66
+ zip_code: value["postalCode"],
67
+ prefecture: value["address1"],
68
+ address1: value["address2"],
69
+ fax: value["faxNo"],
70
+ access: value["access"],
71
+ parking_info: value["parkingInformation"],
72
+ near_station: value["nearestStation"],
73
+ hotel_img_url: value["hotelImageUrl"],
74
+ rakuten_review_count: value["reviewCount"],
75
+ rakuten_review_avg: value["reviewAverage"].to_f
76
+ }
77
+ end
78
+ end
79
+ result["hotels"][0].each do |_key, field|
80
+ field[1].each do |_, value|
81
+ @data_hash[:rakuten_service_review] = value["serviceAverage"].to_f
82
+ @data_hash[:rakuten_location_review] = value["locationAverage"].to_f
83
+ @data_hash[:rakuten_room_review] = value["roomAverage"].to_f
84
+ @data_hash[:rakuten_equipment_review] = value["equipmentAverage"].to_f
85
+ @data_hash[:rakuten_bath_review] = value["bathAverage"].to_f
86
+ @data_hash[:rakuten_meal_review] = value["mealAverage"].to_f
87
+ end
88
+ end
89
+ result["hotels"][0].each do |_key, field|
90
+ field[2].each do |_, value|
91
+ @data_hash[:middle_class_code] = value["middleClassCode"].to_s
92
+ @data_hash[:small_class_code] = value["smallClassCode"].to_s
93
+ @data_hash[:area_name] = value["areaName"].to_s
94
+ @data_hash[:hotel_class_code] = value["hotelClassCode"].to_s
95
+ @data_hash[:checkin_time] = value["checkinTime"].to_s
96
+ @data_hash[:checkout_time] = value["checkoutTime"].to_s
97
+ @data_hash[:last_checkin_time] = value["lastCheckinTime"].to_s
98
+ end
99
+ end
100
+ result["hotels"][0].each do |_key, field|
101
+ field[3].each do |_, value|
102
+ @data_hash[:total_room_num] = value["hotelRoomNum"].to_s
103
+ room_facilities = []
104
+ value["roomFacilities"].each_with_index do |f, i|
105
+ room_facilities[i] = f["item"]
106
+ end
107
+ @data_hash[:room_facilities] = room_facilities
108
+ end
109
+ end
110
+ result["hotels"][0].each do |_key, field|
111
+ field[4].each do |_, value|
112
+ @data_hash[:hotel_policy_note] = value["note"].to_s
113
+ @data_hash[:cancel_policy] = value["cancelPolicy"].to_s
114
+ end
115
+ end
116
+ @data_hash
117
+ end
118
+
119
+ def search_ranking params
120
+ body = {
121
+ middle_class_code: params[:middle_class_code],
122
+ small_class_code: params[:small_class_code],
123
+ detail_class_code: params[:detail_class_code],
124
+ page_num: params[:page_num]
125
+ }
126
+ url = "https://app.rakuten.co.jp/services/api/Travel/SimpleHotelSearch/20170426?applicationId=#{@config[:rakuten_api_key]}&largeClassCode=japan&middleClassCode=#{body[:middle_class_code]}&smallClassCode=#{body[:small_class_code]}&detailClassCode=#{body[:detail_class_code]}&page=#{body[:page_num]}"
127
+ uri = URI.parse(url)
128
+ json = Net::HTTP.get(uri)
129
+ result = JSON.parse(json)
130
+ i = 1
131
+ result["hotels"].each do |key, _value|
132
+ if @config[:rakuten_hotel_id] == key["hotel"][0]["hotelBasicInfo"]["hotelNo"].to_s
133
+ return {
134
+ status: "found",
135
+ hotel_name: key["hotel"][0]["hotelBasicInfo"]["hotelName"],
136
+ area_name: body[:area_name],
137
+ page_num: params[:page_num],
138
+ area_rank: i.to_i + ((body[:page_num].to_i - 1) * 30),
139
+ middle_class_code: body[:middle_class_code],
140
+ small_class_code: body[:small_class_code],
141
+ detail_class_code: body[:detail_class_code]
142
+ }
143
+ end
144
+ i += 1
145
+ end
146
+ { status: "not_found" }
147
+ end
148
+
149
+ def get_page_num detail_class_code
150
+ hotel = hotel_info
151
+ url = "https://app.rakuten.co.jp/services/api/Travel/SimpleHotelSearch/20170426?applicationId=#{@config[:rakuten_api_key]}&largeClassCode=japan&middleClassCode=#{hotel[:middle_class_code]}&smallClassCode=#{hotel[:small_class_code]}&detailClassCode=#{detail_class_code}"
152
+ uri = URI.parse(url)
153
+ json = Net::HTTP.get(uri)
154
+ result = JSON.parse(json)
155
+ {
156
+ small_class_code: hotel[:small_class_code],
157
+ middle_class_code: hotel[:middle_class_code],
158
+ detail_class_code: detail_class_code,
159
+ area_name: hotel[:area_name].to_s,
160
+ page_num: result["pagingInfo"]["pageCount"].to_i
161
+ }
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,532 @@
1
+ module Rakuten
2
+ module Travel
3
+ module Crawler
4
+ class Console
5
+ def initialize params
6
+ @config = {
7
+ login_id: params[:login_id],
8
+ login_pw: params[:login_pw],
9
+ chain: params[:chain] ||= false,
10
+ rakuten_hotel_id: params[:rakuten_hotel_id] ||= 0,
11
+ mode: params[:mode] ||= :chrome
12
+ }
13
+ @wait = Selenium::WebDriver::Wait.new(timeout: 100)
14
+ @driver = HotelPrice.get_selenium_driver @config[:mode]
15
+ if @config[:chain]
16
+ go_to_management_page_chain
17
+ else
18
+ go_to_management_page_single
19
+ end
20
+ end
21
+
22
+ def go_to_management_page_chain
23
+ @driver.get "https://manage.travel.rakuten.co.jp/portal/inn/ry_group.main"
24
+ @driver.find_element(:name, "f_id").send_keys @config[:login_id].to_s
25
+ @driver.find_element(:name, "f_pass").send_keys @config[:login_pw].to_s
26
+ @driver.find_element(:xpath, "/html/body/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/form/table/tbody/tr[2]/td[3]/input").click
27
+ begin
28
+ @driver.find_element(:xpath, "/html/body/center/table/tbody/tr[5]/td[2]/form[3]/input[8]").click
29
+ rescue StandardError
30
+ @driver.find_element(:xpath, "/html/body/center/table/tbody/tr[7]/td[2]/form[3]/input[8]").click
31
+ end
32
+ @i = 0
33
+ (2..21).each do |i|
34
+ rakuten_hotel_id = @driver.find_element(:xpath, "/html/body/center[2]/table/tbody/tr[#{i}]/td[1]").text
35
+ @i = i if @config[:rakuten_hotel_id].to_s == rakuten_hotel_id.to_s
36
+ break if @i == i
37
+ end
38
+ until @i != 0
39
+ @driver.find_element(:xpath, "/html/body/table/tbody/tr/td[2]/form/input[10]").click
40
+ (2..21).each do |i|
41
+ rakuten_hotel_id = @driver.find_element(:xpath, "/html/body/center[2]/table/tbody/tr[#{i}]/td[1]").text
42
+ @i = i if @config[:rakuten_hotel_id].to_s == rakuten_hotel_id.to_s
43
+ break if @i == i
44
+ end
45
+ end
46
+ @driver.find_element(:xpath, "/html/body/center[2]/table/tbody/tr[#{@i}]/td[3]/form/input[10]").click
47
+ @driver
48
+ end
49
+
50
+ def go_to_management_page_single
51
+ @driver.get "https://manage.travel.rakuten.co.jp/portal/inn/mp_kanri_image_up.main"
52
+ @driver.find_element(:name, "f_id").send_keys @config[:login_id]
53
+ @driver.find_element(:name, "f_pass").send_keys @config[:login_pw]
54
+ @driver.find_element(:xpath, "/html/body/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/form/table/tbody/tr[2]/td[3]/input").click
55
+ @driver
56
+ end
57
+
58
+ def go_to_plan_setting
59
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[3]/tbody/tr[2]/td[1]/table/tbody/tr[3]/td/table/tbody/tr[1]/td[2]/input").click
60
+ @wait.until { @driver.find_element(:link_text, "宿泊プラン") }
61
+ @driver.find_element(:link_text, "宿泊プラン").click
62
+ @plans = @driver.find_elements(:class, "h_top_pl_name")
63
+ @driver
64
+ end
65
+
66
+ def get_plan_num
67
+ go_to_plan_setting
68
+ @driver.quit
69
+ @plans.size
70
+ end
71
+
72
+ def save_plan_name
73
+ go_to_plan_setting
74
+ @data = {}
75
+ @plans.each_with_index do |row, i|
76
+ cells = row.find_elements(:css, "td")
77
+ plan_info = row.text.split(":")
78
+ @data[i] = {
79
+ hotel_id: @hotel.id,
80
+ manage_number: plan_info[0],
81
+ plan_name: plan_info[1]
82
+ }
83
+ puts "saved" if RakutenPlan.create(@data[i]).valid?
84
+ end
85
+ @driver.quit
86
+ end
87
+
88
+ def edit_plan
89
+ go_to_plan_setting
90
+ @data = {}
91
+ @plans.each_with_index do |row, i|
92
+ cells = row.find_elements(:css, "td")
93
+ plan_info = row.text.split(":")
94
+ @data[i] = {
95
+ hotel_id: @hotel.id,
96
+ manage_number: plan_info[0],
97
+ plan_name: plan_info[1]
98
+ }
99
+ end
100
+
101
+ (0..@plans.size - 1).each do |i|
102
+ plan = RakutenPlan.find_by(manage_number: @data[i][:manage_number])
103
+ @driver.find_element(:link_text, @data[i][:plan_name]).click
104
+ @driver.find_element(:xpath, "/html/body/form[4]/table[1]/tbody/tr/td/table/tbody[1]/tr[3]/td[2]").text
105
+ flag = []
106
+ flag[0] = "楽天トラベル[宿泊のみ]" if @driver.find_element(:name, "f_tabi_flg").selected?
107
+
108
+ if @driver.find_element(:name, "f_dp_del_flg").selected?
109
+ flag[1] = "ANA楽パック" if @driver.find_element(:name, "f_dp_ana_flg").selected?
110
+ flag[2] = "JAL楽パック" if @driver.find_element(:name, "f_dp_jal_flg").selected?
111
+ end
112
+ flag[3] = "R-with" if @driver.find_element(:name, "f_kobetu_flg").selected?
113
+ begin
114
+ plan_name_p = @driver.find_element(:name, "f_dp_title").attribute("value")
115
+ plan_body_p = @driver.find_element(:name, "f_dp_naiyo").attribute("value")
116
+
117
+ plan_name_r = @driver.find_element(:name, "f_rw_title").attribute("value")
118
+ plan_body_r = @driver.find_element(:name, "f_rw_naiyo").attribute("value")
119
+ rescue StandardError => e
120
+ plan_name_p = ""
121
+ plan_body_p = ""
122
+
123
+ plan_name_r = ""
124
+ plan_body_r = ""
125
+ puts "no dp"
126
+ puts e
127
+ end
128
+
129
+ plan_body = @driver.find_element(:name, "f_naiyo").attribute("value")
130
+
131
+ # inbound = @driver.find_element(:xpath, "/html/body/form[4]/table[1]/tbody/tr/td/table/tbody[1]/tr[11]/td[2]/table/tbody/tr[1]/td/label") if @driver.find_element(:name, "f_multi").selected?
132
+ @room_types = @driver.find_elements(:name, "f_syu")
133
+ @room_type = []
134
+ @room_types.each_with_index do |row, i|
135
+ if row.selected?
136
+ @room_type[i - 1] = row.attribute("value")
137
+ end
138
+ end
139
+ plan_start_y = @driver.find_element(:name, "f_k_nen1").attribute("value")
140
+ plan_start_m = @driver.find_element(:name, "f_k_tuki1").attribute("value")
141
+ plan_start_d = @driver.find_element(:name, "f_k_hi1").attribute("value")
142
+ plan_end_y = @driver.find_element(:name, "f_k_nen2").attribute("value")
143
+ plan_end_m = @driver.find_element(:name, "f_k_tuki2").attribute("value")
144
+ plan_end_d = @driver.find_element(:name, "f_k_hi2").attribute("value")
145
+ stay_start_y = @driver.find_element(:name, "f_nen1").attribute("value")
146
+ stay_start_m = @driver.find_element(:name, "f_tuki1").attribute("value")
147
+ stay_start_d = @driver.find_element(:name, "f_hi1").attribute("value")
148
+ stay_end_y = @driver.find_element(:name, "f_nen2").attribute("value")
149
+ stay_end_m = @driver.find_element(:name, "f_tuki2").attribute("value")
150
+ stay_end_d = @driver.find_element(:name, "f_hi2").attribute("value")
151
+ min_stay = @driver.find_element(:name, "f_min_hak").attribute("value")
152
+ max_stay = @driver.find_element(:name, "f_max_hak").attribute("value")
153
+ checkintime = @driver.find_element(:name, "f_lt_plan_in").attribute("value")
154
+ checkouttime = @driver.find_element(:name, "f_lt_plan_in_limit").attribute("value")
155
+
156
+ @driver.find_elements(:name, "f_credit").each_with_index do |f, i|
157
+ next unless f.selected?
158
+
159
+ @payment_method = if i == 0
160
+ "現金決済または事前カード決済"
161
+ elsif i == 1
162
+ "事前カード決済のみ"
163
+ elsif i == 2
164
+ "現金のみ"
165
+ else
166
+ ""
167
+ end
168
+ end
169
+
170
+ plan_hash = {
171
+ plan_name_p: plan_name_p,
172
+ plan_name_r: plan_name_r,
173
+ plan_body: plan_body.gsub("\n", ""),
174
+ plan_body_p: plan_body_p.gsub("\n", ""),
175
+ plan_body_r: plan_body_r.gsub("\n", ""),
176
+ # :inbound => inbound,
177
+ room_type_ids: @room_type,
178
+ plan_start: plan_start_y + "-" + plan_start_m + "-" + plan_start_d,
179
+ plan_end: plan_end_y + "-" + plan_end_m + "-" + plan_end_d,
180
+ stay_start: stay_start_y + "-" + stay_start_m + "-" + stay_start_d,
181
+ stay_end: stay_end_y + "-" + stay_end_m + "-" + stay_end_d,
182
+ payment_method: @payment_method,
183
+ min_stay: min_stay,
184
+ max_stay: max_stay,
185
+ checkintime: checkintime,
186
+ checkouttime: checkouttime
187
+ }
188
+ puts "plan saved!: #{plan_hash}" if plan.update_attributes(plan_hash)
189
+ @driver.navigate.back
190
+ end
191
+
192
+ @driver.quit
193
+ end
194
+
195
+ def save_room_type
196
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[3]/tbody/tr[2]/td[1]/table/tbody/tr[3]/td/table/tbody/tr[1]/td[2]/input").click
197
+ @wait.until { @driver.find_element(:link_text, "宿泊") }
198
+ @driver.find_element(:link_text, "宿泊").click
199
+ @room_types = @driver.find_elements(:class, "h_top_rm_name")
200
+ @data = {}
201
+ @room_types.each_with_index do |row, i|
202
+ cells = row.find_elements(:css, "td")
203
+ room_type_info = row.text.split(":")
204
+ @data[i] = {
205
+ hotel_id: @hotel.id,
206
+ room_type_id: room_type_info[0],
207
+ room_type_name: room_type_info[1]
208
+ }
209
+ puts "saved" if RakutenRoom.create(@data[i]).valid?
210
+ end
211
+ @driver.quit
212
+ end
213
+
214
+ def edit_room_type
215
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[3]/tbody/tr[2]/td[1]/table/tbody/tr[3]/td/table/tbody/tr[1]/td[2]/input").click
216
+ @wait.until { @driver.find_element(:link_text, "宿泊") }
217
+ @driver.find_element(:link_text, "宿泊").click
218
+ @room_types = @driver.find_elements(:class, "h_top_rm_name")
219
+ @data = {}
220
+ @room_types.each_with_index do |row, i|
221
+ cells = row.find_elements(:css, "td")
222
+ room_type_info = row.text.split(":")
223
+ @data[i] = {
224
+ hotel_id: @hotel.id,
225
+ room_type_id: room_type_info[0],
226
+ room_type_name: room_type_info[1]
227
+ }
228
+ end
229
+ (0..@data.size - 1).each do |room_types|
230
+ @driver.find_element(:link_text, @data[room_types][:room_type_name]).click
231
+ flag = []
232
+ flag[0] = "楽天トラベル[宿泊のみ]" if @driver.find_element(:name, "f_tabimado_del_flg").selected?
233
+
234
+ if @driver.find_element(:name, "f_dp_del_flg").selected?
235
+ flag[1] = "楽天トラベルパッケージ"
236
+ room_type_name_p = @driver.find_element(:name, "f_n_dp_syu").attribute("value")
237
+ remark_p = @driver.find_element(:name, "f_r_dp_syu").attribute("value")
238
+ else
239
+ room_type_name_p = ""
240
+ remark_p = ""
241
+ end
242
+ flag[2] = "R-with" if @driver.find_element(:name, "f_kobetu_del_flg").selected?
243
+ flag[3] = "R-with[割引料金]" if @driver.find_element(:name, "f_vip_del_flg").selected?
244
+
245
+ room_facility = []
246
+ room_facility[0] = "トイレ" if @driver.find_element(:id, "view4_toilet") .selected?
247
+ room_facility[1] = "バス" if @driver.find_element(:id, "view4_bath") .selected?
248
+ room_facility[2] = "シャワーのみ" if @driver.find_element(:id, "view4_shower") .selected?
249
+ img_url = @driver.find_element(:name, "f_img_url").attribute("value")
250
+ @driver.find_elements(:name, "f_pic_flg").each do |f|
251
+ img_url = if f.selected?
252
+ @driver.find_element(:name, "f_img_url").attribute("value")
253
+ else
254
+ ""
255
+ end
256
+ end
257
+
258
+ @driver.find_elements(:name, "f_credit").each_with_index do |f, i|
259
+ next unless f.selected?
260
+
261
+ @payment_method = if i == 0
262
+ "現金決済または事前カード決済"
263
+ elsif i == 1
264
+ "事前カード決済のみ"
265
+ elsif i == 2
266
+ "現金のみ"
267
+ else
268
+ ""
269
+ end
270
+ end
271
+
272
+ if @driver.find_element(:id, "nc_width1").selected?
273
+ mm = @driver.find_element(:id, "su_width1").attribute("value")
274
+ room_size = mm.to_s + "㎡"
275
+ room_size_mm = mm.to_i
276
+ room_size_tatami = ""
277
+ elsif @driver.find_element(:id, "nc_width2").selected?
278
+ mm = @driver.find_element(:id, "nc_width2").attribute("value")
279
+ room_size = mm.to_s + "畳"
280
+ room_size_mm = ""
281
+ room_size_tatami = mm.to_i
282
+ elsif @driver.find_element(:id, "nc_width3").selected?
283
+ room_size = "客室により異なる"
284
+ room_size_mm = ""
285
+ room_size_tatami = ""
286
+ end
287
+ (0..5).each do |i|
288
+ @driver.find_element(:id, "view2_type_#{i}").attribute("value") if @driver.find_element(:id, "view2_type_#{i}").selected?
289
+ end
290
+
291
+ # Pause sort
292
+ # room_facility = %w(禁煙ルーム 喫煙ルーム インターネットができる部屋 露天風呂付き客室 ジャグジーのある客室 離れ客室 コーナールーム 二間以上 洗浄機付きトイレ 高層階 夜景が見える 海が見える 山が見える 湖が見える 川が見える)
293
+ # sort = []
294
+ # for i in 1 .. 13
295
+ # sort[i-1] = room_facility[i-1] if @driver.find_element(:id, "narrow#{i}").selected?
296
+ # end
297
+ # sort.compact!
298
+
299
+ room_db = RakutenRoom.find_by(hotel_id: @hotel.id, room_type_id: @data[room_types][:room_type_id])
300
+ room_type_data = {
301
+ public: flag,
302
+ room_type_name_p: room_type_name_p,
303
+ capacity_min: @driver.find_element(:xpath, "/html/body/table[8]/tbody/tr/td/table[1]/tbody/tr[5]/td[2]").text.gsub(" 名~ 名", ""),
304
+ capacity_max: @driver.find_element(:name, "f_max").attribute("value"),
305
+ remark: @driver.find_element(:name, "f_bikou").attribute("value"),
306
+ remark_p: remark_p,
307
+ room_size: room_size,
308
+ room_size_mm: room_size_mm,
309
+ room_size_tatami: room_size_tatami,
310
+ room_category: room_category,
311
+ room_facility: room_facility,
312
+ room_img: img_url,
313
+ #:sort => sort,
314
+ payment_method: @payment_method
315
+ }
316
+ puts "room type info updated: #{@hotel.id}" if room_db.update_attributes(room_type_data)
317
+ @driver.navigate.back
318
+ end
319
+ @driver.quit
320
+ end
321
+
322
+ def login_check
323
+ exp = @driver.find_element(:xpath, "/html/body/table[1]/tbody/tr[1]/td/table/tbody/tr/td[5]/table/tbody/tr[1]/td").text.gsub("次回パスワード更新日:", "").gsub("※事前にパスワードを変更されたい場合はこちらをご参照ください。\n", "")
324
+ rakuten_hotel_id = @driver.find_element(:xpath, "/html/body/table[1]/tbody/tr[1]/td/table/tbody/tr/td[2]/table/tbody/tr/td").text.gsub("施設番号 : ", "").split("\n")[0]
325
+ {
326
+ status: "success",
327
+ password_exp_date: exp,
328
+ rakuten_hotel_id: rakuten_hotel_id
329
+ }
330
+ rescue StandardError => e
331
+ {
332
+ status: "error",
333
+ error: e.to_s
334
+ }
335
+ end
336
+
337
+ # def get_area_seo_rank
338
+ # @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[1]/tbody/tr[2]/td/table/tbody/tr[1]/td[5]/table/tbody/tr/td/table[1]/tbody/tr[5]/td[2]/font/b")
339
+ # rows = @driver.find_elements(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[1]/tbody/tr[2]/td/table/tbody/tr[1]/td[5]/table/tbody/tr/td/table[1]/tbody/tr[5]")
340
+ # rows.each do |f|
341
+ # cells = f.find_elements(:css, "td").map(&:text)
342
+ # return cells[1]
343
+ # end
344
+ # end
345
+
346
+ def degit2 num
347
+ num = "0#{num}" if num.to_s.size == 1
348
+ num
349
+ end
350
+
351
+ def get_reservation_info
352
+ t = Time.now
353
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[3]/tbody/tr[2]/td[2]/table/tbody/tr[3]/td/input").click
354
+ if t.day == 1
355
+ last_month = degit2 t.prev_month.month.to_i
356
+ yesterday = degit2 t.prev_month.end_of_month.day.to_i
357
+ this_month = degit2 t.month.to_i
358
+ today = degit2 t.day.to_i
359
+ last_month_select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_tuki1"))
360
+ last_month_select.select_by(:value, last_month.to_s)
361
+ yesterday_select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_hi1"))
362
+ yesterday_select.select_by(:value, yesterday.to_s)
363
+ this_month_select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_tuki2"))
364
+ this_month_select.select_by(:value, this_month.to_s)
365
+ today_select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_hi2"))
366
+ today_select.select_by(:value, today.to_s)
367
+ search = @driver.find_element(:xpath, "/html/body/table[7]/tbody/tr[1]/td[4]/input").click
368
+ else
369
+ yesterday = degit2 t.yesterday.day.to_i
370
+ today = degit2 t.day.to_i
371
+ yesterday_select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_hi1"))
372
+ yesterday_select.select_by(:value, yesterday.to_s)
373
+ today_select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_hi2"))
374
+ today_select.select_by(:value, today.to_s)
375
+ search = @driver.find_element(:xpath, "/html/body/table[7]/tbody/tr[1]/td[4]/input").click
376
+ end
377
+
378
+ @wait.until { @driver.find_elements(:xpath, "//tr") }
379
+ sleep 10
380
+ rows = @driver.find_elements(:xpath, "//tr")
381
+ row_num = rows.size
382
+ if row_num != 25
383
+ rows[21..row_num - 4].each do |row|
384
+ cells = row.find_elements(:css, "td").map { |a| a.text.strip.gsub(",", "") }
385
+ point = cells[4].split("\n")[3].gsub("予定ポイント:", "").gsub(" ポイント", "") if cells[4].split("\n")[3].present?
386
+ begin
387
+ if cells[0].size < 7
388
+ @reservation_date = {
389
+ date: Time.now.strftime("%F"),
390
+ reservation_status: cells[0],
391
+ reservation_date: cells[1].split("\n")[2],
392
+ checkindate: cells[1].split("\n")[0],
393
+ checkoutdate: cells[1].split("\n")[1],
394
+ room_type: cells[2].split("\n")[0],
395
+ reservation_number: cells[2].split("\n")[2].split(":")[1],
396
+ payment_on_cash: cells[3].gsub("円", "").to_i,
397
+ price: cells[2].split("\n")[1].split(":")[0].gsub("円人数", ""),
398
+ guest_name: cells[4].split("\n")[0],
399
+ guest_tel: cells[4].split("\n")[1].gsub("(", "").gsub(")", ""),
400
+ point: point
401
+ }
402
+ else
403
+ plan_number = cells[2].split("\n")[0].scan(/\(.+?\)/).last
404
+ @reservation_date = {
405
+ date: Time.now.strftime("%F"),
406
+ hotel_id: @hotel.id,
407
+ reservation_status: cells[0].split("\n\n")[1],
408
+ reservation_date: cells[1].split("\n")[2],
409
+ checkindate: cells[1].split("\n")[0],
410
+ checkoutdate: cells[1].split("\n")[1],
411
+ plan_name: cells[2].split("\n")[0],
412
+ plan_number: plan_number.to_s.gsub("(", "").gsub(")", ""),
413
+ room_type: cells[2].split("\n")[1],
414
+ price: cells[2].split("\n")[2].split(":")[0].gsub("円人数", ""),
415
+ ppl_num: cells[2].split("\n")[2].split(":")[1].gsub("(", "").gsub(")", ""),
416
+ reservation_number: cells[2].split("\n")[3].gsub("予約番号:", ""),
417
+ payment_on_cash: cells[3].gsub("円", "").to_i,
418
+ member_name: cells[4].split("\n")[0],
419
+ guest_name: cells[4].split("\n")[1],
420
+ guest_tel: cells[4].split("\n")[2].gsub("(", "").gsub(")", ""),
421
+ point: point
422
+ }
423
+ end
424
+ puts "saved:#{@reservation_date}" if RakutenReservation.create(@reservation_date).valid?
425
+ rescue StandardError => e
426
+ puts e
427
+ end
428
+ end
429
+ end
430
+ @driver.quit
431
+ end
432
+
433
+ # def daily_data_past
434
+ # @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[2]/tbody/tr[1]/td[1]/table/tbody/tr/td[3]/a/img").click
435
+ # @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[5]/tbody/tr[2]/td[1]/table/tbody/tr[3]/td/table/tbody/tr/td[1]/input").click
436
+ # sleep 3
437
+ # (0..13).each do |i|
438
+ # select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_date"))
439
+ # select.select_by(:index, i)
440
+ # display_data = @driver.find_element(:xpath, '//input[@value = "表示"]')
441
+ # display_data.click
442
+ # rows = @driver.find_elements(:xpath, "//tr")
443
+ # rows[27..58].map do |row|
444
+ # cells = row.find_elements(:css, "td[align=RIGHT]").map { |a| a.text.strip.gsub(",", "") }
445
+ # break unless cells[5] && cells[5].to_i > 1
446
+ # {
447
+ # date: cells[0],
448
+ # reservation_sales: cells[1],
449
+ # access_ppl: cells[2],
450
+ # cvr: cells[3],
451
+ # reservation_unit_price: cells[4],
452
+ # pv: cells[5],
453
+ # pc_retained: cells[6],
454
+ # pc_deliveries: cells[7],
455
+ # pc_total_delivered: cells[8],
456
+ # sp_retained: cells[9],
457
+ # sp_deliveries: cells[10],
458
+ # sp_total_delivered: cells[11]
459
+ # }
460
+ # end
461
+ # end
462
+ # end
463
+
464
+ def daily_data
465
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[2]/tbody/tr[1]/td[1]/table/tbody/tr/td[3]/a/img").click
466
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[5]/tbody/tr[2]/td[1]/table/tbody/tr[3]/td/table/tbody/tr/td[1]/input").click
467
+ sleep 3
468
+ if Time.now.day == 1
469
+ else
470
+ value = if Time.now.month.to_s.size == 2
471
+ Time.now.year.to_s + Time.now.month.to_s + "01"
472
+ else
473
+ Time.now.year.to_s + "0" + Time.now.month.to_s + "01"
474
+ end
475
+ select = Selenium::WebDriver::Support::Select.new(@driver.find_element(:name, "f_date"))
476
+ select.select_by(:value, value)
477
+ end
478
+ @driver.find_element(:xpath, '//input[@value = "表示"]').click
479
+ rows = @driver.find_elements(:xpath, "//tr")
480
+ data = []
481
+ rows[27..58].each do |row|
482
+ cells = row.find_elements(:css, "td[align=RIGHT]").map { |a| a.text.strip.gsub(",", "") }
483
+ break unless cells[5] && cells[5].to_i > 1
484
+ data << {
485
+ date: cells[0],
486
+ reservation_sales: cells[1],
487
+ access_ppl: cells[2],
488
+ cvr: cells[3],
489
+ reservation_unit_price: cells[4],
490
+ pv: cells[5],
491
+ pc_retained: cells[6],
492
+ pc_deliveries: cells[7],
493
+ pc_total_delivered: cells[8],
494
+ sp_retained: cells[9],
495
+ sp_deliveries: cells[10],
496
+ sp_total_delivered: cells[11]
497
+ }
498
+ end
499
+ data
500
+ end
501
+
502
+ def monthly_data_past
503
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[2]/tbody/tr[1]/td[1]/table/tbody/tr/td[3]/a/img").click
504
+ @driver.find_element(:xpath, "/html/body/table[2]/tbody/tr/td[3]/table[5]/tbody/tr[2]/td[1]/table/tbody/tr[3]/td/table/tbody/tr/td[2]/input").click
505
+ @driver.find_element(:xpath, "/html/body/center/table[1]/tbody/tr[2]/td/table/tbody/tr[2]/td/form/input[8]").click
506
+ rows = @driver.find_elements(:xpath, "//tr")
507
+ rows[19..31].map do |row|
508
+ cells = row.find_elements(:css, "td").map { |a| a.text.strip.gsub(",", "") }
509
+ break unless cells[9] && cells[9].to_i > 1
510
+ {
511
+ date: cells[0].gsub("/", "").to_s + "01",
512
+ reservation_sales: cells[1],
513
+ reservation_ppl: cells[2],
514
+ access_ppl: cells[3],
515
+ access_ppl_top_avg: cells[4],
516
+ cvr: cells[5],
517
+ cvr_top_avg: cells[6],
518
+ reservation_unit_price: cells[7],
519
+ reservation_unit_price_top_avg: cells[8],
520
+ pv: cells[9],
521
+ pv_top_avg: cells[10],
522
+ rmail_list_num: cells[11],
523
+ rmail_num: cells[12],
524
+ rmail_delivery_num: cells[13],
525
+ prize: cells[14]
526
+ }
527
+ end
528
+ end
529
+ end
530
+ end
531
+ end
532
+ end
@@ -1,7 +1,7 @@
1
1
  module Rakuten
2
2
  module Travel
3
3
  module Crawler
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,129 @@
1
+ module Rakuten
2
+ module Travel
3
+ module Crawler
4
+ class Web
5
+ def initialize(mode = :chrome)
6
+ @mode = mode
7
+ end
8
+
9
+ def get_price(rakuten_hotel_id, checkin_date, num_adults)
10
+ date = DateTime.now.strftime("%Y-%m-%d")
11
+
12
+ query_string = make_query_string(checkin_date.to_s, num_adults)
13
+ url = "https://hotel.travel.rakuten.co.jp/hotelinfo/plan/#{rakuten_hotel_id}?#{query_string}"
14
+ driver = HotelPrice.get_selenium_driver @mode
15
+ driver.get(url)
16
+ sleep 2
17
+ begin
18
+ driver.find_elements(class_name: "planThumb").first
19
+ rescue
20
+ return ""
21
+ end
22
+ first_plan = driver.find_elements(class_name: "planThumb").first
23
+ hotel_name = driver.find_element(class_name: "rtconds").text
24
+ price = first_plan.find_element(class_name: "vPrice").text.delete("^0-9").to_i
25
+ room_name = first_plan.find_element(tag_name: "h6").text
26
+ plan_name = first_plan.find_element(tag_name: "h4").text
27
+ { date: date, min_price: price, hotel_name: hotel_name, room_name: room_name, plan_name: plan_name }
28
+ rescue StandardError
29
+ { date: date, min_price: 0 }
30
+ end
31
+
32
+ def make_query_string(checkin_date, num_adults)
33
+ cd_args = make_date_args checkin_date
34
+ na_args = make_num_adults_arg num_adults
35
+ "f_teikei=quick&f_hizuke=&f_hak=&f_dai=japan&f_chu=tokyo&f_shou=nishi&f_sai=&f_tel=&f_target_flg=&f_tscm_flg=&f_p_no=&f_custom_code=&f_search_type=&f_camp_id=&f_static=1&f_rm_equip=&#{cd_args}&f_heya_su=1&#{na_args}"
36
+ end
37
+
38
+ def make_date_args checkin_date
39
+ begin
40
+ Date.parse checkin_date
41
+ rescue
42
+ return ""
43
+ end
44
+ t = Date.parse(checkin_date)
45
+ checkin_arg = t.strftime("f_hi1=%d&f_tuki1=%m&f_nen1=%Y")
46
+ checkout_arg = (t + 1).strftime("f_hi2=%d&f_tuki2=%m&f_nen2=%Y")
47
+ "#{checkin_arg}&#{checkout_arg}"
48
+ end
49
+
50
+ def make_num_adults_arg num_adults
51
+ return "" if num_adults.to_i <= 1
52
+ "f_otona_su=#{num_adults}&f_kin2=0&f_kin=&f_s1=0&f_s2=0&f_y1=0&f_y2=0&f_y3=0&f_y4=0"
53
+ end
54
+
55
+ def review rakuten_hotel_id
56
+ driver = HotelPrice.get_selenium_driver @mode
57
+ driver.get("https://travel.rakuten.co.jp/HOTEL/#{rakuten_hotel_id}/review.html")
58
+ sleep 2
59
+ comment_area = driver.find_elements(:class_name, "commentBox")
60
+ data = comment_area.map do |f|
61
+ if f.find_element(class_name: "user").text.include?("投稿者さん")
62
+ username = f.find_element(class_name: "user").text
63
+ generation = 0
64
+ gender = ""
65
+ else
66
+ username = f.find_element(class_name: "user").text.match(/(^.+ )/).to_s.strip
67
+ generation = f.find_element(class_name: "user").text.match(/\[.+代/).to_s.gsub("[", "").gsub("代", "")
68
+ gender = f.find_element(class_name: "user").text.match(%r{/..}).to_s.gsub("/", "")
69
+ end
70
+ {
71
+ date: f.find_element(class_name: "time").text.gsub("年", "").gsub("月", "").gsub("日", ""),
72
+ rate: f.find_element(class_name: "rate").text,
73
+ username: username,
74
+ generation: generation,
75
+ gender: gender,
76
+ rakuten_hotel_id: rakuten_hotel_id,
77
+ comment: f.find_element(class_name: "commentSentence").text
78
+ }
79
+ end
80
+ driver.quit
81
+ data
82
+ end
83
+
84
+ def get_photo_num rakuten_hotel_id
85
+ driver = HotelPrice.get_selenium_driver @mode
86
+ driver.get "https://hotel.travel.rakuten.co.jp/hinfo/#{rakuten_hotel_id}/"
87
+ sleep 2
88
+ num = driver.find_element(:id, "navPht").text.gsub("写真・動画(", "").gsub(")", "").to_i
89
+ driver.quit
90
+ num
91
+ end
92
+
93
+ def get_bf_plan_num rakuten_hotel_id
94
+ driver = HotelPrice.get_selenium_driver @mode
95
+ driver.get "https://hotel.travel.rakuten.co.jp/hotelinfo/plan/#{rakuten_hotel_id}"
96
+ driver.find_element(:id, "focus1").click
97
+ driver.find_element(:id, "dh-squeezes-submit").click
98
+ sleep 3
99
+ plan_num = driver.find_elements(:class, "planThumb")
100
+ driver.quit
101
+ plan_num.size
102
+ end
103
+
104
+ def get_dayuse_plan_num rakuten_hotel_id
105
+ driver = HotelPrice.get_selenium_driver @mode
106
+ driver.get "https://hotel.travel.rakuten.co.jp/hotelinfo/dayuse/?f_no=#{rakuten_hotel_id}"
107
+ sleep 5
108
+ plan_num = driver.find_elements(:class, "planThumb")
109
+ driver.quit
110
+ plan_num.size
111
+ end
112
+
113
+ def get_detail_class_code rakuten_hotel_id
114
+ driver = HotelPrice.get_selenium_driver @mode
115
+ driver.get "https://hotel.travel.rakuten.co.jp/hinfo/?f_no=#{rakuten_hotel_id}"
116
+ {
117
+ status: "found",
118
+ detail_class_code: driver.find_element(id: "breadcrumbs-detail").attribute("href").match(%r{/.\.}).to_s.gsub("/", "").gsub(".", "")
119
+ }
120
+ rescue StandardError
121
+ {
122
+ status: "not_found",
123
+ detail_class_code: ""
124
+ }
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -26,4 +26,12 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = "exe"
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 2.0"
31
+ spec.add_development_dependency "rake", ">= 12.3.3"
32
+ spec.add_development_dependency "rspec", "~> 3.9.0"
33
+ spec.add_runtime_dependency "activesupport", "~> 6.0.2.2"
34
+ spec.add_runtime_dependency "json", "~> 2.3.1"
35
+ spec.add_runtime_dependency "nokogiri", "~> 1.10.9"
36
+ spec.add_runtime_dependency "selenium-webdriver", "~> 3.141"
29
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rakuten-travel-crawler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fumitake Kawasaki
@@ -10,7 +10,105 @@ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
12
  date: 2020-08-03 00:00:00.000000000 Z
13
- dependencies: []
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '2.0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '2.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 12.3.3
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 12.3.3
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 3.9.0
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 3.9.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: activesupport
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 6.0.2.2
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 6.0.2.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: json
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 2.3.1
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 2.3.1
84
+ - !ruby/object:Gem::Dependency
85
+ name: nokogiri
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 1.10.9
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 1.10.9
98
+ - !ruby/object:Gem::Dependency
99
+ name: selenium-webdriver
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3.141'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '3.141'
14
112
  description: Empower World Travel Information Technology
15
113
  email:
16
114
  - fumitake.kawasaki@el-soul.com
@@ -24,12 +122,16 @@ files:
24
122
  - ".rubocop.yml"
25
123
  - ".travis.yml"
26
124
  - Gemfile
125
+ - Gemfile.lock
27
126
  - README.md
28
127
  - Rakefile
29
128
  - bin/console
30
129
  - bin/setup
31
130
  - lib/rakuten/travel/crawler.rb
131
+ - lib/rakuten/travel/crawler/api.rb
132
+ - lib/rakuten/travel/crawler/console.rb
32
133
  - lib/rakuten/travel/crawler/version.rb
134
+ - lib/rakuten/travel/crawler/web.rb
33
135
  - rakuten-travel-crawler.gemspec
34
136
  homepage: https://github.com/elsoul/rakuten-travel-crawler
35
137
  licenses: