hotel_price 0.5.5 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +65 -104
- data/Gemfile.lock +15 -15
- data/LICENSE.txt +67 -21
- data/README.md +21 -2
- data/hotel_price.gemspec +12 -11
- data/lib/hotel_price.rb +10 -6
- data/lib/hotel_price/agoda/agoda_scraper.rb +11 -5
- data/lib/hotel_price/booking/booking_scraper.rb +11 -6
- data/lib/hotel_price/expedia/expedia_scraper.rb +11 -5
- data/lib/hotel_price/jalan/jalan_scraper.rb +13 -6
- data/lib/hotel_price/rakuten/rakuten_console.rb +1 -3
- data/lib/hotel_price/rakuten/rakuten_scraper.rb +22 -19
- data/lib/hotel_price/version.rb +1 -1
- metadata +22 -23
- data/.DS_Store +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf5eb6642b98241831c3b8fef53d49d36e3831739ab7c71638300a70529cc361
|
4
|
+
data.tar.gz: 4acb833993a48783844fc6907eafe1845fd445e63bf7412c2b044da40071799c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bc3d11d78a5ec661800ee5bd9fe8957d75fde7c5388401bb36882e43b30c9c92c928f3f93048bbd3bdbda604074beb558d1b2da073394d5200606dd32ca3c48
|
7
|
+
data.tar.gz: b18e19c6bba93f835aca3bf5766b6660d21caaa279a5ea809ac6a80b099a6037f40d4aa9833b875671cb43ad836053b55eafca4a16f36e8445a5846f70c25adb
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,49 +1,33 @@
|
|
1
|
-
# target_version:
|
2
|
-
# rubocop v0.34.2
|
3
|
-
|
4
|
-
# 自動生成されるものはチェック対象から除外する
|
5
1
|
AllCops:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
DisplayCopNames: true
|
11
|
-
TargetRubyVersion: 2.6.5
|
2
|
+
EnabledByDefault: true
|
3
|
+
|
4
|
+
Style/AndOr:
|
5
|
+
Enabled: false
|
12
6
|
|
13
|
-
##################### Style ##################################
|
14
7
|
Style/ClassAndModuleChildren:
|
15
8
|
Enabled: false
|
16
|
-
# redirect_to xxx and return のイディオムを維持したい
|
17
|
-
Style/AndOr:
|
18
|
-
EnforcedStyle: conditionals
|
19
9
|
|
20
|
-
# 日本語のコメントを許可する
|
21
10
|
Style/AsciiComments:
|
22
11
|
Enabled: false
|
23
12
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Style/
|
28
|
-
|
29
|
-
|
30
|
-
|
13
|
+
Style/SymbolArray:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/WordArray:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Style/MixinGrouping:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/RescueStandardError:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/MethodCallWithArgsParentheses:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/DocumentationMethod:
|
29
|
+
Enabled: false
|
31
30
|
|
32
|
-
# option 等、明示的にハッシュにした方が分かりやすい場合もある
|
33
|
-
Style/BracesAroundHashParameters:
|
34
|
-
Enabled: false
|
35
|
-
|
36
|
-
# Style/CollectionMethods 自体は無効になっているのだが、
|
37
|
-
# https://github.com/bbatsov/rubocop/issues/1084
|
38
|
-
# https://github.com/bbatsov/rubocop/issues/1334
|
39
|
-
# Performance/Detect がこの設定値を見るので PreferredMethods だけ変更しておく。
|
40
|
-
#
|
41
|
-
# デフォルト値から変えたのは
|
42
|
-
# find -> detect
|
43
|
-
# ActiveRecord の find と間違えやすいため
|
44
|
-
# reduce -> inject
|
45
|
-
# detect, reject, select と並べたときに韻を踏んでいるため。
|
46
|
-
# collect -> map を維持しているのは文字数が圧倒的に少ないため。
|
47
31
|
Style/CollectionMethods:
|
48
32
|
PreferredMethods:
|
49
33
|
detect: "detect"
|
@@ -51,152 +35,104 @@ Style/CollectionMethods:
|
|
51
35
|
inject: "inject"
|
52
36
|
reduce: "inject"
|
53
37
|
|
54
|
-
# ドキュメントの無い public class を許可する
|
55
38
|
Style/Documentation:
|
56
39
|
Enabled: false
|
57
40
|
|
58
|
-
# !! のイディオムは積極的に使う
|
59
41
|
Style/DoubleNegation:
|
60
42
|
Enabled: false
|
61
43
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# メソッドチェーンの改行は末尾に . を入れる
|
66
|
-
# REPL に貼り付けた際の暴発を防ぐため
|
44
|
+
Lint/ConstantResolution:
|
45
|
+
Enabled: false
|
46
|
+
|
67
47
|
Layout/DotPosition:
|
68
48
|
EnforcedStyle: trailing
|
69
49
|
|
70
|
-
Layout/LineLength:
|
71
|
-
Enabled: false
|
72
50
|
|
73
51
|
Layout/EmptyLineAfterGuardClause:
|
74
52
|
Enabled: false
|
75
53
|
|
76
|
-
# 明示的に else で nil を返すのは分かりやすいので許可する
|
77
54
|
Style/EmptyElse:
|
78
55
|
EnforcedStyle: empty
|
79
56
|
|
80
|
-
# 桁揃えが綺麗にならないことが多いので migration は除外
|
81
57
|
Layout/ExtraSpacing:
|
82
58
|
Exclude:
|
83
59
|
- "db/migrate/*.rb"
|
84
60
|
|
85
|
-
# いずれかに揃えるのならば `sprintf` や `format` より String#% が好きです
|
86
61
|
Style/FormatString:
|
87
62
|
EnforcedStyle: percent
|
88
63
|
|
89
|
-
|
64
|
+
Style/MissingElse:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Style/StringHashKeys:
|
68
|
+
Exclude:
|
69
|
+
- "spec/queries/*.rb"
|
70
|
+
- "*.gemspec"
|
71
|
+
|
90
72
|
Style/GuardClause:
|
91
73
|
MinBodyLength: 5
|
92
74
|
|
93
|
-
# rake タスクの順序の hash は rocket を許可する
|
94
75
|
Style/HashSyntax:
|
95
76
|
EnforcedStyle: ruby19
|
77
|
+
Exclude:
|
78
|
+
- "**/*.rake"
|
79
|
+
- "Rakefile"
|
96
80
|
|
97
|
-
|
98
|
-
# 条件式の方を意識させたい場合には後置の if/unless を使わない方が分かりやすい
|
99
81
|
Style/IfUnlessModifier:
|
100
82
|
Enabled: false
|
101
83
|
|
102
|
-
# private/protected は一段深くインデントする
|
103
84
|
Style/PreferredHashMethods:
|
104
85
|
EnforcedStyle: short
|
105
86
|
|
106
|
-
# scope 等は複数行でも lambda ではなく ->{} で揃えた方が見た目が綺麗
|
107
87
|
Style/Lambda:
|
108
88
|
Enabled: false
|
109
89
|
|
110
|
-
# 1_000_000 と区切り文字が 2 個以上必要になる場合のみ _ 区切りを必須にする
|
111
90
|
Style/NumericLiterals:
|
112
91
|
MinDigits: 7
|
113
92
|
|
114
|
-
# 正規表現にマッチさせた時の特殊変数の置き換えは Regex.last_match ではなく
|
115
|
-
# 名前付きキャプチャを使って参照したいので auto-correct しない
|
116
93
|
Style/PerlBackrefs:
|
117
94
|
AutoCorrect: false
|
118
95
|
|
119
|
-
# has_ から始まるメソッドは許可する
|
120
|
-
Naming/PredicateName:
|
121
|
-
ForbiddenPrefixes:
|
122
|
-
- "is_"
|
123
|
-
- "have_"
|
124
|
-
NamePrefix:
|
125
|
-
- "is_"
|
126
|
-
- "have_"
|
127
|
-
|
128
|
-
# 特に model 内において、ローカル変数とメソッド呼び出しの区別をつけた方が分かりやすい場合が多い
|
129
96
|
Style/RedundantSelf:
|
130
97
|
Enabled: false
|
131
98
|
|
132
99
|
Style/FrozenStringLiteralComment:
|
133
100
|
Enabled: false
|
134
101
|
|
135
|
-
# 受け取り側で multiple assignment しろというのを明示
|
136
102
|
Style/RedundantReturn:
|
137
103
|
AllowMultipleReturnValues: true
|
138
104
|
|
139
|
-
# spec 内は見た目が綺麗になるので許可
|
140
105
|
Style/Semicolon:
|
141
106
|
Exclude:
|
142
107
|
- "spec/**/*"
|
143
108
|
|
144
|
-
# fail と使い分ける必要ナシ
|
145
109
|
Style/SignalException:
|
146
110
|
EnforcedStyle: only_raise
|
147
111
|
|
148
112
|
Style/MethodDefParentheses:
|
149
113
|
Enabled: false
|
150
114
|
|
151
|
-
# `||` も align に使うことがあるので追加する
|
152
|
-
# Style/SpaceAroundOperators:
|
153
|
-
# MultiSpaceAllowedForOperators:
|
154
|
-
# - "="
|
155
|
-
# - "=>"
|
156
|
-
# - "||"
|
157
|
-
|
158
|
-
# * 式展開したい場合に書き換えるのが面倒
|
159
|
-
# * 文章ではダブルクォートよりもシングルクォートの方が頻出する
|
160
|
-
# ことから EnforcedStyle: double_quotes 推奨
|
161
115
|
Style/StringLiterals:
|
162
116
|
EnforcedStyle: double_quotes
|
163
117
|
|
164
|
-
# auto-correct 時に Style/StringLiterals とカニバって無限ループになる (v0.28.0)
|
165
118
|
Style/StringLiteralsInInterpolation:
|
166
119
|
Enabled: false
|
167
120
|
|
168
|
-
# いくらなんでも inject { |a, e| } は短すぎるので分かりやすい名前をつけたい
|
169
121
|
Style/SingleLineBlockParams:
|
170
122
|
Enabled: false
|
171
123
|
|
172
|
-
# * migrate
|
173
|
-
# * jbuilder
|
174
|
-
# * model の association
|
175
|
-
# * controller の callback
|
176
|
-
# 辺りの桁揃えで引っかかるので全体的にチェックしない
|
177
|
-
# Style/SingleSpaceBeforeFirstArg:
|
178
|
-
# Enabled: false
|
179
|
-
|
180
|
-
|
181
|
-
##################### Lint ##################################
|
182
|
-
|
183
|
-
# * 同名のメソッドがある場合にローカル変数に `_` を付ける
|
184
|
-
# * 一時変数として `_` を付ける
|
185
|
-
# というテクニックは頻出する
|
186
124
|
Lint/UnderscorePrefixedVariableName:
|
187
125
|
Enabled: false
|
188
126
|
|
189
|
-
# 子クラスで実装させるつもりのメソッドで引っかかるので
|
190
127
|
Lint/UnusedMethodArgument:
|
191
128
|
Enabled: false
|
192
129
|
|
193
|
-
##################### Metrics ##################################
|
194
130
|
|
195
131
|
Metrics/AbcSize:
|
196
132
|
Enabled: false
|
197
133
|
|
198
134
|
Metrics/CyclomaticComplexity:
|
199
|
-
|
135
|
+
Max: 10
|
200
136
|
|
201
137
|
Metrics/PerceivedComplexity:
|
202
138
|
Enabled: false
|
@@ -204,6 +140,10 @@ Metrics/PerceivedComplexity:
|
|
204
140
|
Metrics/BlockLength:
|
205
141
|
Enabled: false
|
206
142
|
|
143
|
+
Layout/LineLength:
|
144
|
+
Enabled: false
|
145
|
+
|
146
|
+
|
207
147
|
Metrics/MethodLength:
|
208
148
|
Enabled: false
|
209
149
|
|
@@ -216,14 +156,35 @@ Naming/HeredocDelimiterNaming:
|
|
216
156
|
Naming/AccessorMethodName:
|
217
157
|
Enabled: false
|
218
158
|
|
219
|
-
|
159
|
+
Metrics/ModuleLength:
|
220
160
|
Enabled: false
|
221
161
|
|
222
|
-
Lint/
|
162
|
+
Lint/UnusedBlockArgument:
|
223
163
|
Enabled: false
|
224
164
|
|
225
|
-
|
165
|
+
Lint/RescueException:
|
226
166
|
Enabled: false
|
227
167
|
|
228
|
-
|
168
|
+
Naming/RescuedExceptionsVariableName:
|
169
|
+
Enabled: false
|
170
|
+
|
171
|
+
Bundler/GemComment:
|
172
|
+
Enabled: false
|
173
|
+
|
174
|
+
Style/SafeNavigation:
|
175
|
+
Enabled: false
|
176
|
+
|
177
|
+
Lint/NumberConversion:
|
178
|
+
Enabled: false
|
179
|
+
Style/ConstantVisibility:
|
180
|
+
Enabled: false
|
181
|
+
Style/MutableConstant:
|
182
|
+
Enabled: false
|
183
|
+
Style/Copyright:
|
184
|
+
Enabled: false
|
185
|
+
Style/MultilineTernaryOperator:
|
186
|
+
Enabled: false
|
187
|
+
Layout/MultilineAssignmentLayout:
|
188
|
+
Enabled: false
|
189
|
+
Style/Send:
|
229
190
|
Enabled: false
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hotel_price (0.5.
|
5
|
-
activesupport (~> 6.0.2.
|
6
|
-
json (~> 2.3.
|
4
|
+
hotel_price (0.5.9)
|
5
|
+
activesupport (~> 6.0.2.2)
|
6
|
+
json (~> 2.3.1)
|
7
7
|
nokogiri (~> 1.10.9)
|
8
8
|
selenium-webdriver (~> 3.141)
|
9
9
|
|
@@ -18,28 +18,28 @@ GEM
|
|
18
18
|
zeitwerk (~> 2.2)
|
19
19
|
childprocess (3.0.0)
|
20
20
|
concurrent-ruby (1.1.6)
|
21
|
-
diff-lcs (1.
|
22
|
-
i18n (1.8.
|
21
|
+
diff-lcs (1.4.4)
|
22
|
+
i18n (1.8.5)
|
23
23
|
concurrent-ruby (~> 1.0)
|
24
|
-
json (2.3.
|
24
|
+
json (2.3.1)
|
25
25
|
mini_portile2 (2.4.0)
|
26
|
-
minitest (5.14.
|
27
|
-
nokogiri (1.10.
|
26
|
+
minitest (5.14.1)
|
27
|
+
nokogiri (1.10.10)
|
28
28
|
mini_portile2 (~> 2.4.0)
|
29
29
|
rake (13.0.1)
|
30
30
|
rspec (3.9.0)
|
31
31
|
rspec-core (~> 3.9.0)
|
32
32
|
rspec-expectations (~> 3.9.0)
|
33
33
|
rspec-mocks (~> 3.9.0)
|
34
|
-
rspec-core (3.9.
|
35
|
-
rspec-support (~> 3.9.
|
36
|
-
rspec-expectations (3.9.
|
34
|
+
rspec-core (3.9.2)
|
35
|
+
rspec-support (~> 3.9.3)
|
36
|
+
rspec-expectations (3.9.2)
|
37
37
|
diff-lcs (>= 1.2.0, < 2.0)
|
38
38
|
rspec-support (~> 3.9.0)
|
39
|
-
rspec-mocks (3.9.
|
39
|
+
rspec-mocks (3.9.1)
|
40
40
|
diff-lcs (>= 1.2.0, < 2.0)
|
41
41
|
rspec-support (~> 3.9.0)
|
42
|
-
rspec-support (3.9.
|
42
|
+
rspec-support (3.9.3)
|
43
43
|
rubyzip (2.3.0)
|
44
44
|
selenium-webdriver (3.142.7)
|
45
45
|
childprocess (>= 0.5, < 4.0)
|
@@ -47,7 +47,7 @@ GEM
|
|
47
47
|
thread_safe (0.3.6)
|
48
48
|
tzinfo (1.2.7)
|
49
49
|
thread_safe (~> 0.1)
|
50
|
-
zeitwerk (2.
|
50
|
+
zeitwerk (2.4.0)
|
51
51
|
|
52
52
|
PLATFORMS
|
53
53
|
ruby
|
@@ -56,7 +56,7 @@ DEPENDENCIES
|
|
56
56
|
bundler (~> 2.0)
|
57
57
|
hotel_price!
|
58
58
|
rake (>= 12.3.3)
|
59
|
-
rspec (~> 3.0)
|
59
|
+
rspec (~> 3.9.0)
|
60
60
|
|
61
61
|
BUNDLED WITH
|
62
62
|
2.1.4
|
data/LICENSE.txt
CHANGED
@@ -1,21 +1,67 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
1
|
+
Apache License
|
2
|
+
|
3
|
+
Version 2.0, January 2004
|
4
|
+
|
5
|
+
http://www.apache.org/licenses/
|
6
|
+
|
7
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
8
|
+
|
9
|
+
1. Definitions.
|
10
|
+
|
11
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
12
|
+
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
14
|
+
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
16
|
+
|
17
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
18
|
+
|
19
|
+
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
20
|
+
|
21
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
22
|
+
|
23
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
24
|
+
|
25
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
26
|
+
|
27
|
+
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
28
|
+
|
29
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
30
|
+
|
31
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
32
|
+
|
33
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
34
|
+
|
35
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
36
|
+
|
37
|
+
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
38
|
+
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
39
|
+
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
40
|
+
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
41
|
+
|
42
|
+
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
43
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
44
|
+
|
45
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
46
|
+
|
47
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
48
|
+
|
49
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
50
|
+
|
51
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
52
|
+
|
53
|
+
END OF TERMS AND CONDITIONS
|
54
|
+
|
55
|
+
Copyright 2020 ELSOUL, INC
|
56
|
+
|
57
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
58
|
+
you may not use this file except in compliance with the License.
|
59
|
+
You may obtain a copy of the License at
|
60
|
+
|
61
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
62
|
+
|
63
|
+
Unless required by applicable law or agreed to in writing, software
|
64
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
65
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
66
|
+
See the License for the specific language governing permissions and
|
67
|
+
limitations under the License.
|
data/README.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
[![HotelPrice](https://firebasestorage.googleapis.com/v0/b/el-quest.appspot.com/o/mediaLibrary%2F1589293505170_rakuten-shoken.jpg?alt=media&token=f86b6870-fd3f-42aa-805d-db35cb53a9b6)](https://rubygems.org/gems/hotel_price/)
|
2
|
+
|
3
|
+
<p align="center">
|
4
|
+
|
5
|
+
<a aria-label="Ruby logo" href="https://el-soul.com">
|
6
|
+
<img src="https://badgen.net/badge/icon/Made%20by%20ELSOUL?icon=ruby&label&color=black&labelColor=black">
|
7
|
+
</a>
|
8
|
+
<br/>
|
9
|
+
|
10
|
+
<a aria-label="Ruby Gem version" href="https://rubygems.org/gems/hotel_price">
|
11
|
+
<img alt="" src="https://badgen.net/rubygems/v/hotel_price/latest">
|
12
|
+
</a>
|
13
|
+
<a aria-label="Downloads Number" href="https://rubygems.org/gems/hotel_price">
|
14
|
+
<img alt="" src="https://badgen.net/rubygems/dt/hotel_price">
|
15
|
+
</a>
|
16
|
+
<a aria-label="License" href="https://github.com/elsoul/hotel_price/blob/master/LICENSE">
|
17
|
+
<img alt="" src="https://badgen.net/badge/license/Apache/blue">
|
18
|
+
</a>
|
19
|
+
</p>
|
1
20
|
# HotelPrice
|
2
21
|
This Gem is made for ppl who work at travel industry
|
3
22
|
|
@@ -31,7 +50,7 @@ Rakuten Travel API Reference : https://webservice.rakuten.co.jp/api/simplehotels
|
|
31
50
|
|
32
51
|
|
33
52
|
```ruby
|
34
|
-
hotel = HotelPrice::Rakuten::
|
53
|
+
hotel = HotelPrice::Rakuten::RakutenAPI.new(
|
35
54
|
rakuten_hotel_id: "128552",
|
36
55
|
rakuten_api_key: "api_key"
|
37
56
|
)
|
@@ -56,7 +75,7 @@ HotelPrice::Rakuten::RakutenScraper.get_price("128552", (Date.today + 45.day).to
|
|
56
75
|
|
57
76
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
58
77
|
|
59
|
-
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).
|
78
|
+
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/hotel_price).
|
60
79
|
|
61
80
|
## Contributing
|
62
81
|
|
data/hotel_price.gemspec
CHANGED
@@ -8,20 +8,21 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Fumitake Kawasaki", "James Neve"]
|
9
9
|
spec.email = ["fumitake.kawasaki@el-soul.com", "jamesoneve@gmail.com"]
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage = "https://github.com/
|
14
|
-
spec.license = "
|
15
|
-
spec.metadata = { "source_code_uri" =>"https://github.com/
|
11
|
+
spec.summary = "Scraping Library to get world hotel price"
|
12
|
+
spec.description = "Empower World Travel Information Technology "
|
13
|
+
spec.homepage = "https://github.com/elsoul/hotel_price"
|
14
|
+
spec.license = "Apache-2.0"
|
15
|
+
spec.metadata = { "source_code_uri" => "https://github.com/elsoul/hotel_price" }
|
16
|
+
spec.required_ruby_version = ">= 2.7.0"
|
16
17
|
# spec.metadata["allowed_push_host"] = "https://hotel.el-soul.com"
|
17
18
|
|
18
19
|
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
-
spec.metadata["source_code_uri"] = "https://github.com/
|
20
|
-
spec.metadata["changelog_uri"] = "https://github.com/
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/elsoul/hotel_price"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/elsoul/hotel_price"
|
21
22
|
|
22
23
|
# Specify which files should be added to the gem when it is released.
|
23
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
-
spec.files
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
26
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
27
|
end
|
27
28
|
spec.bindir = "exe"
|
@@ -30,9 +31,9 @@ Gem::Specification.new do |spec|
|
|
30
31
|
|
31
32
|
spec.add_development_dependency "bundler", "~> 2.0"
|
32
33
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
33
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
34
|
-
spec.add_runtime_dependency "activesupport", "~> 6.0.2.
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.9.0"
|
35
|
+
spec.add_runtime_dependency "activesupport", "~> 6.0.2.2"
|
36
|
+
spec.add_runtime_dependency "json", "~> 2.3.1"
|
35
37
|
spec.add_runtime_dependency "nokogiri", "~> 1.10.9"
|
36
38
|
spec.add_runtime_dependency "selenium-webdriver", "~> 3.141"
|
37
|
-
spec.add_runtime_dependency "json", "~> 2.3.0"
|
38
39
|
end
|
data/lib/hotel_price.rb
CHANGED
@@ -23,7 +23,7 @@ module HotelPrice
|
|
23
23
|
def self.rakuten_travel
|
24
24
|
driver = self.get_selenium_driver
|
25
25
|
rakuten_travel_hotel_id = 128552
|
26
|
-
driver.get("https://travel.rakuten.co.jp/HOTEL/#{rakuten_travel_hotel_id
|
26
|
+
driver.get("https://travel.rakuten.co.jp/HOTEL/#{rakuten_travel_hotel_id}/review.html")
|
27
27
|
sleep 2
|
28
28
|
comment_area = driver.find_elements(:class_name, "commentReputationBoth")
|
29
29
|
comment_area.map do |f|
|
@@ -38,17 +38,20 @@ module HotelPrice
|
|
38
38
|
|
39
39
|
protected
|
40
40
|
|
41
|
-
def self.get_selenium_driver(mode =
|
41
|
+
def self.get_selenium_driver(mode = :chrome)
|
42
42
|
case mode
|
43
|
-
when
|
43
|
+
when :firefox_remote_capabilities
|
44
44
|
firefox_capabilities = Selenium::WebDriver::Remote::Capabilities.firefox
|
45
45
|
Selenium::WebDriver.for(:remote, url: "http://hub:4444/wd/hub", desired_capabilities: firefox_capabilities)
|
46
|
-
when
|
46
|
+
when :firefox
|
47
47
|
Selenium::WebDriver.for :firefox
|
48
48
|
else
|
49
|
-
options = Selenium::WebDriver::
|
49
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
50
|
+
options.add_argument("--ignore-certificate-errors")
|
51
|
+
options.add_argument("--disable-popup-blocking")
|
52
|
+
options.add_argument("--disable-translate")
|
50
53
|
options.add_argument("-headless")
|
51
|
-
Selenium::WebDriver.for :
|
54
|
+
Selenium::WebDriver.for :chrome, options: options
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
@@ -58,6 +61,7 @@ module HotelPrice
|
|
58
61
|
# Agoda API key
|
59
62
|
# @param [String]
|
60
63
|
attr_accessor :agoda_api_key
|
64
|
+
attr_accessor :selenium_driver
|
61
65
|
|
62
66
|
def initialize
|
63
67
|
@agoda_api_key = nil
|
@@ -2,12 +2,18 @@ require "date"
|
|
2
2
|
|
3
3
|
module HotelPrice::Agoda
|
4
4
|
class AgodaScraper
|
5
|
-
|
5
|
+
@mode
|
6
|
+
|
7
|
+
def initialize(mode = :chrome)
|
8
|
+
@mode = mode
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_price(agoda_hotel_id, checkin_date, num_adults)
|
6
12
|
date = DateTime.now.strftime("%Y-%m-%d")
|
7
13
|
|
8
14
|
query_string = make_query_string(checkin_date.to_s, num_adults)
|
9
15
|
url = "https://www.agoda.com/ja-jp/#{agoda_hotel_id}.html?#{query_string}"
|
10
|
-
driver = HotelPrice.get_selenium_driver mode
|
16
|
+
driver = HotelPrice.get_selenium_driver @mode
|
11
17
|
driver.get(url)
|
12
18
|
sleep 2
|
13
19
|
|
@@ -26,20 +32,20 @@ module HotelPrice::Agoda
|
|
26
32
|
{ checkin_date: checkin_date, min_price: price, hotel_name: hotel_name, room_name: room_name }
|
27
33
|
end
|
28
34
|
|
29
|
-
def
|
35
|
+
def make_query_string(checkin_date, num_adults)
|
30
36
|
cd_args = make_date_args checkin_date
|
31
37
|
na_args = make_num_adults_arg num_adults
|
32
38
|
"#{cd_args}&#{na_args}&rooms=1&travellerType=-1"
|
33
39
|
end
|
34
40
|
|
35
|
-
def
|
41
|
+
def make_date_args checkin_date
|
36
42
|
Date.parse checkin_date rescue return ""
|
37
43
|
t = Date.parse(checkin_date)
|
38
44
|
checkin_arg = t.strftime("checkIn=%Y-%m-%d")
|
39
45
|
"#{checkin_arg}&los=2"
|
40
46
|
end
|
41
47
|
|
42
|
-
def
|
48
|
+
def make_num_adults_arg num_adults
|
43
49
|
return "" if num_adults.to_i <= 1
|
44
50
|
"adults=#{num_adults}"
|
45
51
|
end
|
@@ -2,13 +2,18 @@ require "date"
|
|
2
2
|
|
3
3
|
module HotelPrice::Booking
|
4
4
|
class BookingScraper
|
5
|
+
@mode
|
5
6
|
|
6
|
-
def
|
7
|
+
def initialize(mode = :chrome)
|
8
|
+
@mode = mode
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_price(booking_hotel_id, checkin_date, num_adults)
|
7
12
|
date = DateTime.now.strftime("%Y-%m-%d")
|
8
13
|
|
9
14
|
query_string = make_query_string(checkin_date.to_s, num_adults)
|
10
15
|
url = "https://www.booking.com/hotel/jp/#{booking_hotel_id}.ja.html?#{query_string}"
|
11
|
-
driver = HotelPrice.get_selenium_driver mode
|
16
|
+
driver = HotelPrice.get_selenium_driver @mode
|
12
17
|
driver.get(url)
|
13
18
|
sleep 2
|
14
19
|
|
@@ -29,13 +34,13 @@ module HotelPrice::Booking
|
|
29
34
|
{ checkin_date: checkin_date, min_price: price, hotel_name: hotel_name, room_name: room_name }
|
30
35
|
end
|
31
36
|
|
32
|
-
def
|
37
|
+
def make_query_string(checkin_date, num_adults)
|
33
38
|
cd_args = make_date_args checkin_date
|
34
39
|
na_args = make_num_adults_arg num_adults
|
35
40
|
"#{cd_args}&#{na_args}&dist=0&do_availability_check=1&hp_avform=1&hp_group_set=0&no_rooms=1&origin=hp&sb_price_type=total&src=hotel&tab=1&type=total&lang=ja&selected_currency=JPY"
|
36
41
|
end
|
37
42
|
|
38
|
-
def
|
43
|
+
def make_date_args checkin_date
|
39
44
|
Date.parse checkin_date rescue return ""
|
40
45
|
t = Date.parse(checkin_date)
|
41
46
|
checkin_arg = t.strftime("checkin_monthday=%d&checkin_year_month=%Y-%m")
|
@@ -43,9 +48,9 @@ module HotelPrice::Booking
|
|
43
48
|
"#{checkin_arg}&#{checkout_arg}"
|
44
49
|
end
|
45
50
|
|
46
|
-
def
|
51
|
+
def make_num_adults_arg num_adults
|
47
52
|
return "" if num_adults.to_i <= 1
|
48
53
|
"group_adults=#{num_adults}&group_children=0"
|
49
54
|
end
|
50
55
|
end
|
51
|
-
end
|
56
|
+
end
|
@@ -2,12 +2,18 @@ require "date"
|
|
2
2
|
|
3
3
|
module HotelPrice::Expedia
|
4
4
|
class ExpediaScraper
|
5
|
-
|
5
|
+
@mode
|
6
|
+
|
7
|
+
def initialize(mode = :chrome)
|
8
|
+
@mode = mode
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_price(expedia_hotel_id, checkin_date, num_adults)
|
6
12
|
date = DateTime.now.strftime("%Y-%m-%d")
|
7
13
|
|
8
14
|
query_string = make_query_string(checkin_date.to_s, num_adults)
|
9
15
|
url = "https://www.expedia.co.jp/ja/#{expedia_hotel_id}.Hotel-Information?#{query_string}"
|
10
|
-
driver = HotelPrice.get_selenium_driver mode
|
16
|
+
driver = HotelPrice.get_selenium_driver @mode
|
11
17
|
driver.get(url)
|
12
18
|
sleep 2
|
13
19
|
|
@@ -26,13 +32,13 @@ module HotelPrice::Expedia
|
|
26
32
|
{ checkin_date: checkin_date, min_price: price, hotel_name: hotel_name, room_name: room_name }
|
27
33
|
end
|
28
34
|
|
29
|
-
def
|
35
|
+
def make_query_string(checkin_date, num_adults)
|
30
36
|
cd_args = make_date_args checkin_date
|
31
37
|
na_args = make_num_adults_arg num_adults
|
32
38
|
"#{cd_args}&#{na_args}&x_pwa=1&rfrr=HSR&pwa_ts=1583335742618&swpToggleOn=true®ionId=3250&destination=Sapporo%2C+Hokkaido%2C+Japan&destType=MARKET&neighborhoodId=6290332&selected=5224778&sort=recommended&top_dp=5686&top_cur=JPY"
|
33
39
|
end
|
34
40
|
|
35
|
-
def
|
41
|
+
def make_date_args checkin_date
|
36
42
|
Date.parse checkin_date rescue return ""
|
37
43
|
t = Date.parse(checkin_date)
|
38
44
|
checkin_arg = t.strftime("chkin=%Y-%m-%d")
|
@@ -40,7 +46,7 @@ module HotelPrice::Expedia
|
|
40
46
|
"#{checkin_arg}&#{checkout_arg}"
|
41
47
|
end
|
42
48
|
|
43
|
-
def
|
49
|
+
def make_num_adults_arg num_adults
|
44
50
|
return "" if num_adults.to_i <= 1
|
45
51
|
"rm1=a#{num_adults}"
|
46
52
|
end
|
@@ -1,11 +1,17 @@
|
|
1
1
|
module HotelPrice::Jalan
|
2
2
|
class JalanScraper
|
3
|
-
|
3
|
+
@mode
|
4
|
+
|
5
|
+
def initialize(mode = :chrome)
|
6
|
+
@mode = mode
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_price(jalan_hotel_id, checkin_date, num_adults)
|
4
10
|
date = DateTime.now.strftime("%Y-%m-%d")
|
5
11
|
|
6
12
|
query_string = make_query_string(checkin_date.to_s, num_adults)
|
7
13
|
url = "https://www.jalan.net/yad#{jalan_hotel_id}/plan/?screenId=UWW3101&yadNo=#{jalan_hotel_id}&#{query_string}"
|
8
|
-
driver = HotelPrice.get_selenium_driver mode
|
14
|
+
driver = HotelPrice.get_selenium_driver @mode
|
9
15
|
driver.get(url)
|
10
16
|
sleep 2
|
11
17
|
@price_box = []
|
@@ -20,25 +26,26 @@ module HotelPrice::Jalan
|
|
20
26
|
plan_name: f.find_element(class_name: "p-planCassette__header").text
|
21
27
|
}
|
22
28
|
rescue StandardError
|
29
|
+
{ date: date, min_price: 0 }
|
23
30
|
end
|
24
31
|
end
|
25
|
-
@price_box.sort_by { |_a, _b, c| c }.reverse.first
|
32
|
+
@price_box.sort_by { |_a, _b, c| c }.reverse.first || { date: date, min_price: 0 }
|
26
33
|
rescue StandardError
|
27
34
|
{ date: date, min_price: 0 }
|
28
35
|
end
|
29
36
|
|
30
|
-
def
|
37
|
+
def make_query_string(checkin_date, num_adults)
|
31
38
|
cd_args = make_date_args checkin_date
|
32
39
|
na_args = make_num_adults_arg num_adults
|
33
40
|
"rootCd=7701&callbackHistFlg=1&contHideFlg=1&reSearchFlg=1&roomCrack=100000&smlCd=121108&distCd=01&#{cd_args}&stayCount=1&roomCount=1&#{na_args}&minPrice=0&maxPrice=999999"
|
34
41
|
end
|
35
42
|
|
36
|
-
def
|
43
|
+
def make_date_args checkin_date
|
37
44
|
Date.parse checkin_date rescue return ""
|
38
45
|
Date.parse(checkin_date).strftime("stayYear=%Y&stayMonth=%m&stayDay=%d")
|
39
46
|
end
|
40
47
|
|
41
|
-
def
|
48
|
+
def make_num_adults_arg num_adults
|
42
49
|
return "" if num_adults.to_i < 1
|
43
50
|
"adultNum=#{num_adults}"
|
44
51
|
end
|
@@ -6,7 +6,7 @@ module HotelPrice::Rakuten
|
|
6
6
|
login_pw: params[:login_pw],
|
7
7
|
chain: params[:chain] ||= false,
|
8
8
|
rakuten_hotel_id: params[:rakuten_hotel_id] ||= 0,
|
9
|
-
mode: params[:mode] ||=
|
9
|
+
mode: params[:mode] ||= :chrome
|
10
10
|
}
|
11
11
|
@wait = Selenium::WebDriver::Wait.new(timeout: 100)
|
12
12
|
@driver = HotelPrice.get_selenium_driver @config[:mode]
|
@@ -320,14 +320,12 @@ module HotelPrice::Rakuten
|
|
320
320
|
def login_check
|
321
321
|
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", "")
|
322
322
|
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]
|
323
|
-
@driver.quit
|
324
323
|
{
|
325
324
|
status: "success",
|
326
325
|
password_exp_date: exp,
|
327
326
|
rakuten_hotel_id: rakuten_hotel_id
|
328
327
|
}
|
329
328
|
rescue StandardError => e
|
330
|
-
@driver.quit
|
331
329
|
{
|
332
330
|
status: "error",
|
333
331
|
error: e.to_s
|
@@ -3,12 +3,18 @@ module HotelPrice::Rakuten
|
|
3
3
|
## mode 1 - docker selenium
|
4
4
|
## mode 2 - debug
|
5
5
|
class RakutenScraper
|
6
|
-
|
6
|
+
@mode
|
7
|
+
|
8
|
+
def initialize(mode = :chrome)
|
9
|
+
@mode = mode
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_price(rakuten_hotel_id, checkin_date, num_adults)
|
7
13
|
date = DateTime.now.strftime("%Y-%m-%d")
|
8
14
|
|
9
15
|
query_string = make_query_string(checkin_date.to_s, num_adults)
|
10
16
|
url = "https://hotel.travel.rakuten.co.jp/hotelinfo/plan/#{rakuten_hotel_id}?#{query_string}"
|
11
|
-
driver = HotelPrice.get_selenium_driver mode
|
17
|
+
driver = HotelPrice.get_selenium_driver @mode
|
12
18
|
driver.get(url)
|
13
19
|
sleep 2
|
14
20
|
driver.find_elements(class_name: "planThumb").first rescue return ""
|
@@ -22,13 +28,13 @@ module HotelPrice::Rakuten
|
|
22
28
|
{ date: date, min_price: 0 }
|
23
29
|
end
|
24
30
|
|
25
|
-
def
|
31
|
+
def make_query_string(checkin_date, num_adults)
|
26
32
|
cd_args = make_date_args checkin_date
|
27
33
|
na_args = make_num_adults_arg num_adults
|
28
34
|
"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}"
|
29
35
|
end
|
30
36
|
|
31
|
-
def
|
37
|
+
def make_date_args checkin_date
|
32
38
|
Date.parse checkin_date rescue return ""
|
33
39
|
t = Date.parse(checkin_date)
|
34
40
|
checkin_arg = t.strftime("f_hi1=%d&f_tuki1=%m&f_nen1=%Y")
|
@@ -36,13 +42,13 @@ module HotelPrice::Rakuten
|
|
36
42
|
"#{checkin_arg}&#{checkout_arg}"
|
37
43
|
end
|
38
44
|
|
39
|
-
def
|
45
|
+
def make_num_adults_arg num_adults
|
40
46
|
return "" if num_adults.to_i <= 1
|
41
47
|
"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"
|
42
48
|
end
|
43
49
|
|
44
|
-
def
|
45
|
-
driver = HotelPrice.get_selenium_driver mode
|
50
|
+
def review rakuten_hotel_id
|
51
|
+
driver = HotelPrice.get_selenium_driver @mode
|
46
52
|
driver.get("https://travel.rakuten.co.jp/HOTEL/#{rakuten_hotel_id}/review.html")
|
47
53
|
sleep 2
|
48
54
|
comment_area = driver.find_elements(:class_name, "commentBox")
|
@@ -70,8 +76,8 @@ module HotelPrice::Rakuten
|
|
70
76
|
data
|
71
77
|
end
|
72
78
|
|
73
|
-
def
|
74
|
-
driver = HotelPrice.get_selenium_driver mode
|
79
|
+
def get_photo_num rakuten_hotel_id
|
80
|
+
driver = HotelPrice.get_selenium_driver @mode
|
75
81
|
driver.get "https://hotel.travel.rakuten.co.jp/hinfo/#{rakuten_hotel_id}/"
|
76
82
|
sleep 2
|
77
83
|
num = driver.find_element(:id, "navPht").text.gsub("写真・動画(", "").gsub(")", "").to_i
|
@@ -79,8 +85,8 @@ module HotelPrice::Rakuten
|
|
79
85
|
num
|
80
86
|
end
|
81
87
|
|
82
|
-
def
|
83
|
-
driver = HotelPrice.get_selenium_driver mode
|
88
|
+
def get_bf_plan_num rakuten_hotel_id
|
89
|
+
driver = HotelPrice.get_selenium_driver @mode
|
84
90
|
driver.get "https://hotel.travel.rakuten.co.jp/hotelinfo/plan/#{rakuten_hotel_id}"
|
85
91
|
driver.find_element(:id, "focus1").click
|
86
92
|
driver.find_element(:id, "dh-squeezes-submit").click
|
@@ -90,20 +96,17 @@ module HotelPrice::Rakuten
|
|
90
96
|
plan_num.size
|
91
97
|
end
|
92
98
|
|
93
|
-
def
|
94
|
-
driver = HotelPrice.get_selenium_driver mode
|
95
|
-
driver.get "https://hotel.travel.rakuten.co.jp/hotelinfo/
|
96
|
-
sleep 5
|
97
|
-
driver.find_element(:id, "du-radio").click
|
98
|
-
driver.find_element(:id, "dh-submit").click
|
99
|
+
def get_dayuse_plan_num rakuten_hotel_id
|
100
|
+
driver = HotelPrice.get_selenium_driver @mode
|
101
|
+
driver.get "https://hotel.travel.rakuten.co.jp/hotelinfo/dayuse/?f_no=#{rakuten_hotel_id}"
|
99
102
|
sleep 5
|
100
103
|
plan_num = driver.find_elements(:class, "planThumb")
|
101
104
|
driver.quit
|
102
105
|
plan_num.size
|
103
106
|
end
|
104
107
|
|
105
|
-
def
|
106
|
-
driver = HotelPrice.get_selenium_driver mode
|
108
|
+
def get_detail_class_code rakuten_hotel_id
|
109
|
+
driver = HotelPrice.get_selenium_driver @mode
|
107
110
|
driver.get "https://hotel.travel.rakuten.co.jp/hinfo/?f_no=#{rakuten_hotel_id}"
|
108
111
|
{
|
109
112
|
status: "found",
|
data/lib/hotel_price/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotel_price
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fumitake Kawasaki
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-08-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -45,70 +45,70 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: 3.9.0
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version:
|
55
|
+
version: 3.9.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: activesupport
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 6.0.2.
|
62
|
+
version: 6.0.2.2
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 6.0.2.
|
69
|
+
version: 6.0.2.2
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
71
|
+
name: json
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
76
|
+
version: 2.3.1
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
83
|
+
version: 2.3.1
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
85
|
+
name: nokogiri
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
88
|
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
90
|
+
version: 1.10.9
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
97
|
+
version: 1.10.9
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
99
|
+
name: selenium-webdriver
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: '3.141'
|
105
105
|
type: :runtime
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
111
|
+
version: '3.141'
|
112
112
|
description: 'Empower World Travel Information Technology '
|
113
113
|
email:
|
114
114
|
- fumitake.kawasaki@el-soul.com
|
@@ -118,7 +118,6 @@ executables:
|
|
118
118
|
extensions: []
|
119
119
|
extra_rdoc_files: []
|
120
120
|
files:
|
121
|
-
- ".DS_Store"
|
122
121
|
- ".gitignore"
|
123
122
|
- ".rspec"
|
124
123
|
- ".rubocop.yml"
|
@@ -152,13 +151,13 @@ files:
|
|
152
151
|
- lib/hotel_price/rakuten/rakuten_console.rb
|
153
152
|
- lib/hotel_price/rakuten/rakuten_scraper.rb
|
154
153
|
- lib/hotel_price/version.rb
|
155
|
-
homepage: https://github.com/
|
154
|
+
homepage: https://github.com/elsoul/hotel_price
|
156
155
|
licenses:
|
157
|
-
-
|
156
|
+
- Apache-2.0
|
158
157
|
metadata:
|
159
|
-
source_code_uri: https://github.com/
|
160
|
-
homepage_uri: https://github.com/
|
161
|
-
changelog_uri: https://github.com/
|
158
|
+
source_code_uri: https://github.com/elsoul/hotel_price
|
159
|
+
homepage_uri: https://github.com/elsoul/hotel_price
|
160
|
+
changelog_uri: https://github.com/elsoul/hotel_price
|
162
161
|
post_install_message:
|
163
162
|
rdoc_options: []
|
164
163
|
require_paths:
|
@@ -167,14 +166,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
166
|
requirements:
|
168
167
|
- - ">="
|
169
168
|
- !ruby/object:Gem::Version
|
170
|
-
version:
|
169
|
+
version: 2.7.0
|
171
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
171
|
requirements:
|
173
172
|
- - ">="
|
174
173
|
- !ruby/object:Gem::Version
|
175
174
|
version: '0'
|
176
175
|
requirements: []
|
177
|
-
rubygems_version: 3.
|
176
|
+
rubygems_version: 3.1.4
|
178
177
|
signing_key:
|
179
178
|
specification_version: 4
|
180
179
|
summary: Scraping Library to get world hotel price
|
data/.DS_Store
DELETED
Binary file
|