qunar 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: abb1c8b487e496de74a3d1aba1011297d09ec936
4
- data.tar.gz: c31420590fc4344ff961faa8cf5a74c57dd66b49
3
+ metadata.gz: e4ba1d679946abe2f3016259dc8e0b4e7ee0379c
4
+ data.tar.gz: c55780c6f8d0986e17d8886dcf4b650076117b8e
5
5
  SHA512:
6
- metadata.gz: 7595b89f23e5424c60c5f4d640d51bdc9b31da7a27802390ee2716df5b3909ffccf5d48b4f164cdad164d5d99a04e43ffac0d4abf05c912258b822f96ff66052
7
- data.tar.gz: c0805458111c8147aff0a921abf7f58b1d9f28fc755f7311e00cbe574f8197af1062945db20e55222cb2daa798cef0acef16ec0fa4ee2289715f1eabe4d007b9
6
+ metadata.gz: e938a846a8799b42590edfca4e09b777dbe04094210b3830128b3727d735d492f7a3721783e2f75e97a61115754b4ab852fda934df45df5c8411ed243956ba65
7
+ data.tar.gz: 5df5d5d986d06d5249bd76891cc5ff253bf1949563b275bc031865f88ed2d51a7c305ee70eb97036919c97db459476de5b34f3530ade39ffe2d8e2f7c77b403f
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/lib/qunar/hotel.rb CHANGED
@@ -4,7 +4,7 @@ module Qunar
4
4
  class Hotel
5
5
  BASEURI = "http://hotel.qunar.com"
6
6
  def initialize(hotelId)
7
- #super
7
+ #super
8
8
  raise "id should be string" if !hotelId.instance_of?(String)
9
9
  @HotelSEQ = hotelId #hotelId is "cityurl_hotelcode"
10
10
  @cityurl = hotelId[0..hotelId.rindex("_",-1)-1]
@@ -14,24 +14,11 @@ module Qunar
14
14
  @hotel = Nokogiri::HTML page
15
15
  end
16
16
 
17
- def parse_mixkey #get some kind of code unkown
18
- uri = URI(File.join(BASEURI, 'city', @cityurl, "dt-#{@hotelcode}"))
19
- http_res = HTTParty.get uri.to_s
20
- res = Nokogiri::HTML http_res
21
- node = res.search('//span[@id="eyKxim"]').first
22
- return nil if node.nil?
23
- return node.text
24
- end
25
-
26
17
  def name #get the name of the hotel
27
18
  @hotel.search("//div[@class='htl-info fr']//span").first.text.strip
28
- # name_tag = @hotel.search("//div[@class='htl-info fr']/h2/span").first
29
- # return nil if name_tag.nil?
30
- # name_tag.text[0..name_tag.text.index("\n",1)].strip
31
19
  end
32
20
 
33
21
  def star #get the level of the hotel
34
- #name_tag = @hotel.search('//div[@class="eriefinfo"]//dt').first
35
22
  name_tag = @hotel.search('//div[@class="htl-info fr"]//em[@class="dangci"]').first
36
23
  return 0 if name_tag.nil?
37
24
  if name_tag.text.include?'经济型'
@@ -67,22 +54,18 @@ module Qunar
67
54
  @hotelcode = @hotelcode
68
55
  end
69
56
 
70
- def address
57
+ def address
71
58
  @hotel.search("//p[@class='adress']/span").first['title'].strip
72
59
  #return "" if address.nil?
73
60
  #return address['title'].strip
74
61
  end
75
62
 
76
63
  def phone
77
- #phone ||= @hotel.search("//li[contains(text(),'电话:')]").text.sub('电话:','').strip
78
64
  @hotel.search("//dl[@class='inform-list']//cite").first.text.sub('电话','').strip
79
65
  end
80
66
 
81
67
  #the description of the hotel
82
- def desc
83
- #desc = @hotel.search("p[@class='summery less_summery']").text
84
- #desc = @hotel.search("p[@class='summery expan_summery']").text if desc.empty?
85
- #desc.gsub(/[[:space:]]/, '')
68
+ def desc
86
69
  @hotel.search("div[@class='introduce']/p").text
87
70
  end
88
71
 
@@ -92,20 +75,8 @@ module Qunar
92
75
  #date.strip
93
76
  @hotel.search("dl[@class='inform-list']//cite")[-2].text.sub("年开业",'')
94
77
  end
95
- =begin
96
- #简略描述
97
- def abstract_desc
98
- abstract_desc = @hotel.search("p[@class='h_desc']").first
99
- return "" if abstract_desc.nil?
100
- return abstract_desc.text.sub('描述:','').strip
101
- end
102
78
 
103
- def brand
104
- brand ||= @hotel.search("//li[contains(text(),'所属品牌:')]").text.sub('所属品牌:','').strip
105
- brand.strip
106
- end
107
- =end
108
- def reference_price
79
+ def reference_price
109
80
  match_data = @hotel.to_s.match(/var\s*miniRetailPrice\s*=\s*\'\d+\';/)
110
81
  return 0 if match_data.nil?
111
82
  match_data = match_data[0].match(/[\d]+/)
@@ -115,98 +86,12 @@ module Qunar
115
86
 
116
87
  def coordinate
117
88
  xy = @hotel.to_s.match(/hotelPoint=\[(\d+\.\d+),(\d+\.\d+)\];/)
118
- puts xy
119
89
  if xy.nil?
120
90
  return [0.0,0.0]
121
91
  else
122
92
  return [xy[1],xy[2]]
123
93
  end
124
94
  end
125
- #设施
126
- def facilities
127
- facility = @hotel.search("//div[@class=\"roundmilieu htintroborder\"]").first
128
- facilities = Array.new()
129
- unless facility.nil?
130
- facility.search("dl").each do |dl|
131
- ele = Hash.new
132
- facility_cata = dl.search("dt").first.text.delete(':')
133
- ele1 = Array.new
134
- dl.search("dd/ul/li").each do |facility_type|
135
- ele1 << facility_type.text
136
- end
137
- ele['name'] = facility_cata
138
- ele['info'] = ele1
139
- facilities << ele
140
- end
141
- end
142
- facilities
143
- end
144
95
 
145
- #交通信息 not runable
146
- =begin
147
- def traffic
148
- traffic = "http://hotel.qunar.com/detail/detailMapData.jsp?seq=#{@hotelcode}&type=traffic,canguan,jingdian,ent"
149
- traffic = HTTParty.get traffic
150
- traffic_data = Array.new()
151
- if traffic['ret'] == true
152
- traffic['data']['ent'].each do |line|
153
- ele = Hash.new
154
- ele['name'] = line['name']
155
- ele['distance'] = line['distance']
156
- traffic_data << ele
157
- end
158
- end
159
- end
160
-
161
- def decorate_date #not found
162
- match_data = @hotel.to_s.match(/最后装修时间:\d+年/)
163
- return "" if match_data.nil?
164
- match_data[0].strip
165
- end
166
-
167
-
168
- def comments
169
- url = "http://review.qunar.com/api/h/#{@hotelcode}/detail/rank/v1/page/1"
170
- comments = HTTParty.get url
171
- comments = JSON.parse comments
172
- comments['data']['list'].map{|comment| JSON.parse(comment['content'])['feedContent'] }
173
- end
174
-
175
- #评论总数
176
- def total_comment
177
- url = "http://review.qunar.com/api/h/#{@hotelcode}/detail/rank/page/1?rate=all"
178
- body = HTTParty.get url
179
- match_data = body.match(/"count":\d+/)
180
- return "0" if match_data.nil?
181
- match_data[0].sub(/\"count\":/,"").strip
182
- end
183
- #好评
184
- def good_comment
185
- url = "http://review.qunar.com/api/h/#{@hotelcode}/detail/rank/page/1?rate=positive"
186
- body = HTTParty.get url
187
- match_data = body.match(/"count":\d+/)
188
- return "0" if match_data.nil?
189
- match_data[0].sub(/\"count\":/,"")
190
- end
191
-
192
-
193
- def images
194
- url = "http://hotel.qunar.com/render/hotelDetailAllImage.jsp?hotelseq=#{@hotelcode}"
195
- body = HTTParty.get url
196
- body = JSON.parse(body)
197
- return body['data']["all"] if(body['ret'])
198
- end
199
-
200
- def score
201
- url = "http://review.qunar.com/api/h/#{@hotelcode}/detail"
202
- body = HTTParty.get url
203
- begin
204
- body = JSON.parse body
205
- return body["data"]["score"].strip
206
- rescue Exception => e
207
- return "0.0"
208
- end
209
- end
210
- =end
211
96
  end
212
97
  end
data/lib/qunar/rank.rb CHANGED
@@ -1,11 +1,7 @@
1
- #require 'rubygems'
2
1
  require 'capybara'
3
- #require 'selenium-webdriver'
4
2
  require 'nokogiri'
5
3
  require 'capybara-webkit'
6
4
 
7
- #headless = Headless.new
8
- #headless.start
9
5
  Capybara.current_driver = :webkit
10
6
  Capybara.default_selector = :xpath
11
7
  Capybara.app_host = 'http://hotel.qunar.com'
@@ -32,21 +28,26 @@ module Qunar
32
28
  file.puts @page
33
29
  end
34
30
  end
35
- =begin
36
- File.open("test1.html","w") do |file|
37
- file.puts @page
38
- end
39
- =end
40
31
 
41
- def room
42
- room = {}
32
+
33
+ def rooms
34
+ rooms = []
35
+ # room
43
36
  @hotel.search("//ul[@class='htl-type-list clrfix']/li").each do |li|
37
+ room = {}
44
38
  type = li.search("span[@class='type-name']").first.text.strip
39
+ room['room_type'] = type
40
+ room['otas'] = []
41
+ # ota
45
42
 
46
43
  li.search("div[@class='similar-type-agent-list']/div/div").each do |row|
47
- ota_pic = row.search("div[@class='agent-pic']/img").first['src'].strip
44
+ otas = {}
45
+
46
+ ota = row.search("div[@class='profile-tit']").first.text.strip
47
+ otas['ota'] = ota
48
48
 
49
49
  bookable = row.search("a[@class='btn-book']/span").first.text.strip
50
+ otas['bookable'] = bookable
50
51
 
51
52
  insurance = row.search("p[@class='dbt-ct']").first
52
53
  if insurance == nil
@@ -54,6 +55,7 @@ module Qunar
54
55
  else
55
56
  insurance = true
56
57
  end
58
+ otas['insurance'] = insurance
57
59
 
58
60
  coupon = row.search("span[@class='fan']/em[@class='pr'] |span[@class='fan laps']/em[@class='pr']").first
59
61
  if coupon == nil
@@ -61,6 +63,7 @@ module Qunar
61
63
  else
62
64
  coupon = coupon.text.sub(/¥/,'').strip
63
65
  end
66
+ otas['coupon'] = coupon
64
67
 
65
68
  prepay = row.search("span[@title='需要预先支付房款']").first
66
69
  if prepay == nil
@@ -68,106 +71,22 @@ module Qunar
68
71
  else
69
72
  prepay = true
70
73
  end
74
+ otas['prepay'] = prepay
71
75
 
72
76
  price = row.search("p[@class='final-price ']/b").first.text.strip
73
- neat_price = row.search("p[@class='count_pr']").first.text
74
-
75
- puts "#{type} #{ota_pic} #{price} #{neat_price} #{coupon} #{prepay} #{insurance} #{bookable}"
76
- end
77
-
78
- end
79
-
80
- return 0
81
- end
82
-
83
-
84
- end
85
- end
86
-
87
-
88
-
89
- =begin
90
- require 'nokogiri'
91
- require 'headless'
92
- require 'capybara'
93
- require 'capybara/dsl'
94
- module Qunar
95
- class Rank
96
- include Capybara::DSL
97
- BASEURI = "http://hotel.qunar.com"
98
- def initialize(hotelId)
99
- raise "id should be string" if !hotelId.instance_of?(String) #ckeck the whether hotelId is a string
100
- @HotelSEQ = hotelId #hotelId is "cityurl_hotelcode"
101
- @cityurl = hotelId[0..hotelId.rindex("_",-1)-1]
102
- @hotelcode = hotelId[hotelId.rindex("_",-1)+1..hotelId.length]
103
- end
104
-
105
- def parse_mixkey
106
- uri = URI(File.join(BASEURI, 'city', @cityurl, "dt-#{@hotelcode}")) #ex:http://hotel.qunar.com/city/beijing_city/dt-2933/
107
- http_res = HTTParty.get uri.to_s
108
- res = Nokogiri::HTML http_res
109
- node = res.search('//span[@id="eyKxim"]').first
110
- return nil if node.nil?
111
- return node.text
112
- end
77
+ otas['price'] = price
113
78
 
114
- def set_cookies
115
- headless = Headless.new
116
- headless.start
117
- Capybara.current_driver = :selenium
118
- Capybara.app_host = BASEURI
119
- Capybara.default_wait_time = 10
120
- begin
121
- visit "/city/#{@cityurl}/dt-#{@hotelcode}/"
122
- rescue Errno::ECONNREFUSED => e
123
- raise
124
- end
125
- @cookies = {}
126
- Capybara.current_session.driver.browser.manage.all_cookies.each { |cookie| @cookies[cookie[:name]] = cookie[:value] }
127
- end
79
+ neat_price = row.search("p[@class='count_pr']").first.children[1].to_s
80
+ otas['neat_price'] = neat_price
128
81
 
129
- def load_price_ajax
130
- mixKey = parse_mixkey
131
- set_cookies
132
- raise QunarMixKeyParsedException if mixKey.nil?
133
- uri = URI(File.join(BASEURI, 'render', 'detailV2.jsp'))
134
- params = {:fromDate=>Date.today+2, :toDate=>Date.today+3, :cityurl=>@cityurl, :HotelSEQ=>@HotelSEQ, :mixKey=>mixKey}
135
- headers = Hash.new
136
- headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 5.1; rv:26.0) Gecko/20100101 Firefox/26.0'
137
- headers['Connection'] = 'keep-alive'
138
- headers['Accept-Encoding'] = 'gzip, deflate'
139
- headers['Cookie'] = @cookies.map{|k, v| k+'='+v}.join('; ')
140
- uri.query = URI.encode_www_form(params)
141
- res = HTTParty.get(uri.to_s, :headers=>headers)
142
- File.open("test1.html","w") do |file|
143
- puts res
144
- end
82
+ room['otas'] << otas
83
+ end
84
+ rooms << room
145
85
 
146
- json_ajax = parse_json_from_response_body(res.body)
147
- if !json_ajax['errcode'].nil? and json_ajax['errcode'].eql?110
148
- raise QunarIpBlockException,json_ajax
149
86
  end
150
- raise QunarIpBlockException,json_ajax if !json_ajax['errcode'].nil? and json_ajax['errcode'].eql?110
151
- @ranks = json_ajax['result'].values
152
- end
153
-
154
- def rank(ota, room)
155
- @ranks.each { |rank| return rank[15]+1 if rank[3].eql?room and rank[6].eql?ota and rank[9].eql?1 }
156
- return nil
87
+ return rooms
157
88
  end
158
89
 
159
- def rooms
160
- @rooms ||= @ranks.map { |e| e[3] }.uniq
161
- end
162
90
 
163
- def otas
164
- @otas ||= @ranks.map{|e| e[6] }.uniq
165
- end
166
-
167
- def parse_json_from_response_body(res)
168
- JSON.parse(res.gsub(/[()]/,""))
169
- end
170
-
171
91
  end
172
92
  end
173
- =end
data/lib/qunar/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Qunar
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/qunar.rb CHANGED
@@ -1,6 +1,6 @@
1
- require_relative 'qunar/version'
2
- require_relative 'qunar/hotel'
3
- require_relative 'qunar/rank'
1
+ require 'qunar/version'
2
+ require 'qunar/hotel'
3
+ require 'qunar/rank'
4
4
 
5
5
  module Qunar
6
6
  # Your code goes here...
@@ -0,0 +1,88 @@
1
+ require 'qunar/hotel'
2
+
3
+ describe Qunar::Hotel do
4
+ bj_sample = Qunar::Hotel.new('beijing_city_2933')
5
+
6
+ it "has name '北京诺富特三元酒店'" do
7
+ # subject.name.should == '北京诺富特三元酒店'
8
+ expect(bj_sample.name).to eq '北京诺富特三元酒店'
9
+ end
10
+
11
+ it "has star 4" do
12
+ expect(bj_sample.star).to eq 4
13
+ end
14
+
15
+ it "has citynameEn 'beijing'" do
16
+ expect(bj_sample.citynameEn).to eq "beijing"
17
+ end
18
+
19
+ it "has citynameCn '北京' " do
20
+ expect(bj_sample.citynameCn).to eq "北京"
21
+ end
22
+
23
+ it "has id '2933' " do
24
+ expect(bj_sample.id).to eq "2933"
25
+ end
26
+
27
+ it "has address '北京朝阳区曙光西里A5号18座' " do
28
+ expect(bj_sample.address).to eq '北京朝阳区曙光西里A5号18座'
29
+ end
30
+
31
+ it "has phone '010-58296666'" do
32
+ expect(bj_sample.phone).to eq "010-58296666"
33
+ end
34
+
35
+
36
+ it "has desc '北京诺富特三元酒店坐落于三元桥东北角,紧靠地铁十号线以及机场快轨线,周边老国展中心和商业中心繁盛,交通十分便捷。 距机场仅 约16分钟车程。酒店距使馆区、燕莎购物中心、秀水街和3个展览中心仅几分钟车程。' " do
37
+ expect(bj_sample.desc).to eq "北京诺富特三元酒店坐落于三元桥东北角,紧靠地铁十号线以及机场快轨线,周边老国展中心和商业中心繁盛,交通十分便捷。 距机场仅 约16分钟车程。酒店距使馆区、燕莎购物中心、秀水街和3个展览中心仅几分钟车程。"
38
+ end
39
+
40
+
41
+ it "has opentime '2008' " do
42
+ expect(bj_sample.opentime).to eq "2008"
43
+ end
44
+
45
+ it "has reference_price '498'" do
46
+ expect(bj_sample.reference_price).to eq '498'
47
+ end
48
+
49
+
50
+ it "has coordinate ['39.961277','116.45537'] " do
51
+ expect(bj_sample.coordinate).to eq ['39.961277','116.45537']
52
+ end
53
+
54
+ #=====================================================================================================
55
+
56
+
57
+ gz_sample = Qunar::Hotel.new('guangzhou_49')
58
+
59
+ it "has name '广州长隆酒店'" do
60
+ # subject.name.should == '北京诺富特三元酒店'
61
+ expect(gz_sample.name).to eq '广州长隆酒店'
62
+ end
63
+
64
+ it "has star 5" do
65
+ expect(gz_sample.star).to eq 5
66
+ end
67
+
68
+ it "has citynameEn 'guangzhou'" do
69
+ expect(gz_sample.citynameEn).to eq "guangzhou"
70
+ end
71
+
72
+ it "has citynameCn '广州' " do
73
+ expect(gz_sample.citynameCn).to eq "广州"
74
+ end
75
+
76
+ it "has id '49' " do
77
+ expect(gz_sample.id).to eq "49"
78
+ end
79
+
80
+ it "has address '广州市番禺区番禺大道' " do
81
+ expect(gz_sample.address).to eq '广州市番禺区番禺大道'
82
+ end
83
+
84
+ it "has phone '020-84786838'" do
85
+ expect(gz_sample.phone).to eq "020-84786838"
86
+ end
87
+
88
+ end
data/spec/rank_spec.rb ADDED
@@ -0,0 +1,87 @@
1
+ require 'qunar/rank'
2
+
3
+ describe Qunar::Rank do
4
+ sample = Qunar::Rank.new('beijing_city_2933')
5
+
6
+ it "has 7 rooms" do
7
+ # when directly check the hash object the Chinese charactervalue is saved as format like "\u6807\u51C6\u53CC\u5E8A\u623F", it is not been parsed here, so it is not equal to chinese charactor, it's just a sequnce of coding,it needs to be parse,then it could show as Chinese character.
8
+ # room = {"room_type" => "\u6807\u51C6\u53CC\u5E8A\u623F", "ota" => "\u827A\u9F99\u65C5\u884C\u7F51", "bookable" => "\u9884\u8BA2", "insurance" => true, "coupon" => "0", "prepay" => false, "price" => "918", "neat_price" => "918"}
9
+ expect(sample.rooms.size).to eq 7
10
+ end
11
+
12
+ it "first room names '标准双床房'" do
13
+ expect(sample.rooms.first['room_type']).to eq '标准双床房'
14
+ end
15
+
16
+ it "second room names '标准大床房'" do
17
+ expect(sample.rooms[1]['room_type']).to eq '标准大床房'
18
+ end
19
+
20
+ it "has 22 otas for the first room type '标准双床房'" do
21
+ expect(sample.rooms.first['otas'].size).to eq 22
22
+ end
23
+
24
+ it "has 20 otas for the second room type '标准大床房'" do
25
+ expect(sample.rooms[1]['otas'].size).to eq 20
26
+ end
27
+
28
+ it "first ota of first roomtype names '艺龙旅行网'" do
29
+ #puts subject.rooms.first['otas'].first['ota']
30
+ expect(sample.rooms.first['otas'].first['ota']).to eq '艺龙旅行网'
31
+ end
32
+
33
+ it "first ota of second roomtype names Expedia" do
34
+ #puts subject.rooms.first['otas'].first['ota']
35
+ expect(sample.rooms[1]['otas'].first['ota']).to eq 'Booking.com'
36
+ end
37
+
38
+ it "first ota of first roomtype is bookable" do
39
+ #puts subject.rooms.first['otas'].first['bookable']
40
+ expect(sample.rooms.first['otas'].first['bookable']).to eq '预订'
41
+ end
42
+
43
+ it "last ota of first roomtype is bookable" do
44
+ #puts subject.rooms[-1]['otas'].first['bookable']
45
+ expect(sample.rooms.first['otas'][-1]['bookable']).to eq '订完'
46
+ end
47
+
48
+ it "first ota of first roomtype need insurance" do
49
+ expect(sample.rooms.first['otas'].first['insurance']).to eq true
50
+ end
51
+
52
+ it "third ota of first roomtype need insurance" do
53
+ #puts subject.rooms.first['otas'][2]['insurance']
54
+ expect(sample.rooms.first['otas'][2]['insurance']).to eq false
55
+ end
56
+
57
+ it "first ota of first roomtype coupon is 0" do
58
+ expect(sample.rooms.first['otas'].first['coupon']).to eq '0'
59
+ end
60
+
61
+
62
+ it "first ota of first roomtype need prepay" do
63
+ expect(sample.rooms.first['otas'].first['prepay']).to eq false
64
+ end
65
+
66
+ it "second ota of first roomtype need prepay" do
67
+ expect(sample.rooms.first['otas'][1]['prepay']).to eq true
68
+ end
69
+
70
+ it "first ota of first roomtype price" do
71
+ expect(sample.rooms.first['otas'].first['price']).to eq '918'
72
+ end
73
+
74
+ it "sixth ota of first roomtype price" do
75
+ expect(sample.rooms.first['otas'][5]['price']).to eq '638'
76
+ end
77
+
78
+ it "first ota of first roomtype neat_price" do
79
+ expect(sample.rooms.first['otas'].first['neat_price']).to eq '918'
80
+ end
81
+
82
+ it "sixth ota of first roomtype neat_price" do
83
+ #puts subject.rooms.first['otas'][5]['neat_price']
84
+ expect(sample.rooms.first['otas'][5]['neat_price']).to eq '734'
85
+ end
86
+
87
+ end