espider 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/espider.gemspec +28 -0
- data/lib/espider.rb +10 -0
- data/lib/espider/api/baidu/map.rb +9 -0
- data/lib/espider/api/baidu/map/place.rb +53 -0
- data/lib/espider/api/dianping.rb +13 -0
- data/lib/espider/api/dianping/base.rb +35 -0
- data/lib/espider/api/dianping/business.rb +38 -0
- data/lib/espider/api/dianping/coupon.rb +0 -0
- data/lib/espider/api/dianping/deal.rb +0 -0
- data/lib/espider/api/dianping/metadata.rb +28 -0
- data/lib/espider/api/dianping/params.rb +34 -0
- data/lib/espider/api/dianping/review.rb +0 -0
- data/lib/espider/exceptions.rb +2 -0
- data/lib/espider/front/baidu/map/hotel.rb +12 -0
- data/lib/espider/front/baidu/map/hotel/detail.rb +60 -0
- data/lib/espider/front/baidu/map/hotel/list.rb +46 -0
- data/lib/espider/front/dianping.rb +7 -0
- data/lib/espider/front/dianping/hotel.rb +10 -0
- data/lib/espider/front/dianping/hotel/detail.rb +80 -0
- data/lib/espider/front/dianping/hotel/list.rb +56 -0
- data/lib/espider/front/front.rb +23 -0
- data/lib/espider/front/kuxun.rb +7 -0
- data/lib/espider/front/kuxun/detail.rb +100 -0
- data/lib/espider/front/qunar.rb +9 -0
- data/lib/espider/front/qunar/base.rb +25 -0
- data/lib/espider/front/qunar/hotel.rb +173 -0
- data/lib/espider/front/qunar/rank.rb +60 -0
- data/lib/espider/front/ta.rb +27 -0
- data/lib/espider/front/ta/advisor.rb +12 -0
- data/lib/espider/front/ta/daodao.rb +16 -0
- data/lib/espider/version.rb +3 -0
- data/spec/advisor_front_rank_spec.rb +11 -0
- data/spec/baidu_map_api_spec.rb +31 -0
- data/spec/baidu_map_front_spec.rb +53 -0
- data/spec/dadao_front_rank_spec.rb +11 -0
- data/spec/dianping_api_business_spec.rb +29 -0
- data/spec/dianping_api_metadata_spec.rb +44 -0
- data/spec/dianping_front_detail_spec.rb +27 -0
- data/spec/dianping_front_list_spec.rb +17 -0
- data/spec/kuxun_front_detail_spec.rb +26 -0
- data/spec/qunar_front_detail_spec.rb +74 -0
- data/spec/qunar_front_rank_alive_spec.rb +12 -0
- data/spec/qunar_front_rank_spec.rb +28 -0
- data/spec/spec_helper.rb +1 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 09e1fd711323b14fe56bd4acc1c3e8c4f451db93
|
4
|
+
data.tar.gz: 4975bc93cd785fb82abe3a79edb2a8be5a2406a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba15746f81e8658df9cf4dee7fe9aa7b949c085be8325af393260520bc79f5603376fabad5732412bc8adc4f17e52926291573155c501fc98e11d0c1864ba217
|
7
|
+
data.tar.gz: 06957b4ca9760e8834649affd3518687fb2385dec5fe8c5283af9895213f9593f596d0858a8cb3e1da0a59c06dfe5dbdb5e7bf52bd245922290e8ea29fb893ad
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Espider
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'espider'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install espider
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/espider.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'espider/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "espider"
|
8
|
+
spec.version = ESpider::VERSION
|
9
|
+
spec.authors = ["lei"]
|
10
|
+
spec.email = ["littlell@126.com"]
|
11
|
+
spec.description = %q{elong spider}
|
12
|
+
spec.summary = %q{elong spider for qunar,dianyping etc.}
|
13
|
+
spec.homepage = "http://ruby-china.org/littlell"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake", "~> 0"
|
23
|
+
|
24
|
+
# spec.add_dependency "date", "~> 0"
|
25
|
+
spec.add_dependency "nokogiri", "~> 0"
|
26
|
+
spec.add_dependency "httparty", "~> 0"
|
27
|
+
spec.add_dependency "json", "~> 0"
|
28
|
+
end
|
data/lib/espider.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'espider/version'
|
2
|
+
require 'espider/front/qunar'
|
3
|
+
require 'espider/front/front'
|
4
|
+
require 'espider/front/dianping/hotel'
|
5
|
+
require 'espider/front/baidu/map/hotel'
|
6
|
+
require 'espider/front/ta'
|
7
|
+
require 'espider/api/baidu/map'
|
8
|
+
require 'espider/api/dianping'
|
9
|
+
require 'espider/front/kuxun'
|
10
|
+
require 'espider/exceptions'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'httparty'
|
3
|
+
require 'uri'
|
4
|
+
module ESpider
|
5
|
+
module Baidu
|
6
|
+
module Map
|
7
|
+
module API
|
8
|
+
class Place
|
9
|
+
FORMAT = {:JSON=>'json',:XML=>'xml'}
|
10
|
+
INFO = {:ALL=>2,:BASIC=>1}
|
11
|
+
FIRST_PAGE_NUM = -1
|
12
|
+
BaseUri = "http://api.map.baidu.com/place/v2/search?"
|
13
|
+
def initialize(key,page_size=10,info_type=INFO[:ALL],format=FORMAT[:JSON])
|
14
|
+
@key = key
|
15
|
+
@page_size = page_size
|
16
|
+
@info_type = info_type
|
17
|
+
@format = format
|
18
|
+
end
|
19
|
+
#城市内检索
|
20
|
+
# http://api.map.baidu.com/place/v2/search?ak=您的密钥&output=json&query=酒店&page_size=10&page_num=5&scope=2®ion=北京
|
21
|
+
def search_by_city(query,region)
|
22
|
+
@params = {:ak=>@key,:output=>@format,:query=>query,:page_size=>@page_size,:page_num=>FIRST_PAGE_NUM,:scope=>@info_type,:region=>region}
|
23
|
+
end
|
24
|
+
#矩形区域搜索
|
25
|
+
#http://api.map.baidu.com/place/v2/search?ak=您的密钥&output=json&query=酒店&page_size=10&page_num=5&scope=2&bounds=39.915,116.404,39.975,116.414
|
26
|
+
def search_by_rect(query,bounds)
|
27
|
+
@params = {:ak=>@key,:output=>@format,:query=>query,:page_size=>@page_size,:page_num=>FIRST_PAGE_NUM,:scope=>@info_type,:bounds=>bounds}
|
28
|
+
end
|
29
|
+
#圆形区域检索
|
30
|
+
# http://api.map.baidu.com/place/v2/search?ak=您的密钥&output=json&query=酒店&page_size=10&page_num=5&scope=2&location=39.915,116.404&radius=2000
|
31
|
+
def search_by_round(query,location,radius)
|
32
|
+
@params = {:ak=>@key,:output=>@format,:query=>query,:page_size=>@page_size,:page_num=>FIRST_PAGE_NUM,:scope=>@info_type,:location=>location,:radius=>radius}
|
33
|
+
end
|
34
|
+
def next_page
|
35
|
+
@params[:page_num] = @params[:page_num] + 1
|
36
|
+
get_page
|
37
|
+
end
|
38
|
+
def get_page
|
39
|
+
@page = HTTParty.get File.join(BaseUri + URI.escape(@params.collect{|k,v| "#{k}=#{v}"}.join('&')))
|
40
|
+
@page.body
|
41
|
+
end
|
42
|
+
def page_code
|
43
|
+
@page.code
|
44
|
+
end
|
45
|
+
def total
|
46
|
+
parsed_json = JSON.parse @page.body
|
47
|
+
parsed_json['total']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ESpider
|
2
|
+
module API
|
3
|
+
module Dianping
|
4
|
+
end
|
5
|
+
end
|
6
|
+
end
|
7
|
+
require 'espider/api/dianping/base'
|
8
|
+
require 'espider/api/dianping/review'
|
9
|
+
require 'espider/api/dianping/metadata'
|
10
|
+
require 'espider/api/dianping/deal'
|
11
|
+
require 'espider/api/dianping/coupon'
|
12
|
+
require 'espider/api/dianping/business'
|
13
|
+
require 'espider/api/dianping/params'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'httparty'
|
3
|
+
require 'uri'
|
4
|
+
module ESpider
|
5
|
+
module API
|
6
|
+
module Dianping
|
7
|
+
class Base
|
8
|
+
Domain = "http://api.dianping.com"
|
9
|
+
Version = "v1"
|
10
|
+
def initialize(appkey,app_secret)
|
11
|
+
@appkey = appkey
|
12
|
+
@app_secret = app_secret
|
13
|
+
@params = {}
|
14
|
+
end
|
15
|
+
def calc_digest
|
16
|
+
@params.delete(:appkey)
|
17
|
+
@params.delete(:sign)
|
18
|
+
digest = Digest::SHA1.hexdigest(@appkey+@params.sort.map{|e| e[0].to_s+e[1].to_s}.join('')+@app_secret).upcase
|
19
|
+
@params[:appkey] = @appkey
|
20
|
+
@params[:sign] = digest
|
21
|
+
end
|
22
|
+
def get
|
23
|
+
calc_digest
|
24
|
+
@uri.query = URI.encode_www_form(@params)
|
25
|
+
res = HTTParty.get @uri.to_s
|
26
|
+
res.body
|
27
|
+
end
|
28
|
+
def next_page
|
29
|
+
@params[:page] = @params[:page] + 1
|
30
|
+
get
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
module ESpider
|
3
|
+
module API
|
4
|
+
module Dianping
|
5
|
+
class Business < ESpider::API::Dianping::Base
|
6
|
+
BaseUri = File.join(Domain,Version,self.name.demodulize.downcase)
|
7
|
+
include ESpider::API::Dianping
|
8
|
+
def find_businesses(city=Param::EMPTY,region=Param::EMPTY,latitude=Param::EMPTY,longitude=Param::EMPTY)
|
9
|
+
return false if city.empty? and (longitude.empty? or latitude.empty?)
|
10
|
+
return false if city.empty? and !region.empty?
|
11
|
+
@uri = URI File.join(BaseUri,__method__.to_s)
|
12
|
+
method(__method__).parameters.each do |e|
|
13
|
+
param_value = eval(e[1].to_s)
|
14
|
+
@params[e[1]]=param_value unless param_value.to_s.empty?
|
15
|
+
end
|
16
|
+
@params[:page] = Param::FIRST_PAGE
|
17
|
+
@params[:platform] = Param::WEB_URL
|
18
|
+
@params[:out_offset_type] = Param::OUT_GAODE_OFFSET
|
19
|
+
@params[:offset_type] = Param::GAODE_OFFSET
|
20
|
+
@params[:format] = Param::JSON
|
21
|
+
@params[:limit] = Param::DEFAULT_LIMIT
|
22
|
+
@params[:sort] = Param::SORT_BY_STAR
|
23
|
+
true
|
24
|
+
end
|
25
|
+
def find_businesses_by_region
|
26
|
+
|
27
|
+
end
|
28
|
+
def get_single_business(business_id)
|
29
|
+
@uri = URI File.join(BaseUri,__method__.to_s)
|
30
|
+
@params['business_id'] = business_id
|
31
|
+
end
|
32
|
+
def set_category(category)
|
33
|
+
@params[:category] = category
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
module ESpider
|
3
|
+
module API
|
4
|
+
module Dianping
|
5
|
+
class Metadata < ESpider::API::Dianping::Base
|
6
|
+
BaseUri = File.join(Domain,Version,self.name.demodulize.downcase)
|
7
|
+
Methods = [
|
8
|
+
'get_cities_with_businesses',
|
9
|
+
'get_regions_with_businesses',
|
10
|
+
'get_categories_with_businesses',
|
11
|
+
'get_cities_with_deals',
|
12
|
+
'get_regions_with_deals',
|
13
|
+
'get_categories_with_deals',
|
14
|
+
'get_cities_with_coupons',
|
15
|
+
'get_regions_with_coupons',
|
16
|
+
'get_categories_with_coupons'
|
17
|
+
]
|
18
|
+
Methods.each do |method|
|
19
|
+
define_method(method){init_methods(method)}
|
20
|
+
end
|
21
|
+
def init_methods(method_name)
|
22
|
+
@uri = URI File.join(BaseUri,method_name.to_s)
|
23
|
+
calc_digest
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ESpider
|
2
|
+
module API
|
3
|
+
module Dianping
|
4
|
+
module Param
|
5
|
+
EMPTY = ""
|
6
|
+
NO_OFFSET = 0
|
7
|
+
GAODE_OFFSET = 1
|
8
|
+
TUBA_OFFSET = 2
|
9
|
+
OUT_GAODE_OFFSET = 1
|
10
|
+
OUT_TUBA_OFFSET = 2
|
11
|
+
DEFAULT_RADIUS = 1000
|
12
|
+
WEB_URL = 1
|
13
|
+
MOBILE_URL = 2
|
14
|
+
HAS_COUPON = 1
|
15
|
+
NO_COUPON = 0
|
16
|
+
HAS_DEAL = 1
|
17
|
+
NO_DEAL = 0
|
18
|
+
SORT_DEFAULT = 1
|
19
|
+
SORT_BY_STAR = 2
|
20
|
+
SORT_BY_RATE = 3
|
21
|
+
SORT_BY_ENV = 4
|
22
|
+
SORT_BY_SERV = 5
|
23
|
+
SORT_BY_COMM = 6
|
24
|
+
SORT_BY_DIST = 7
|
25
|
+
SORT_BY_MPRICE_LOW = 8
|
26
|
+
SORT_BY_MPRICE_HIGH = 9
|
27
|
+
JSON = 'json'
|
28
|
+
XML = 'xml'
|
29
|
+
DEFAULT_LIMIT = 20
|
30
|
+
FIRST_PAGE = 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
File without changes
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'httparty'
|
3
|
+
require 'uri'
|
4
|
+
module ESpider
|
5
|
+
module Front
|
6
|
+
module Baidu
|
7
|
+
module Map
|
8
|
+
module Hotel
|
9
|
+
class Detail
|
10
|
+
HotelUri = "http://map.baidu.com/detail"
|
11
|
+
def initialize(uid)
|
12
|
+
url = HotelUri + "?qt=ninf&uid=#{uid}"
|
13
|
+
@hotel = JSON.parse HTTParty.get url
|
14
|
+
true
|
15
|
+
end
|
16
|
+
def hotel_name
|
17
|
+
@hotel['content']['name']
|
18
|
+
end
|
19
|
+
def hotel_addr
|
20
|
+
@hotel['content']['addr']
|
21
|
+
end
|
22
|
+
def hotel_tel
|
23
|
+
@hotel['content']['phone']
|
24
|
+
end
|
25
|
+
def hotel_geo
|
26
|
+
@hotel['content']['geo'].split(/;/)[0].sub(/\d+\|/,"").split(',')
|
27
|
+
end
|
28
|
+
def hotel_star
|
29
|
+
@hotel['content']['ext']['rich_info']['level']
|
30
|
+
end
|
31
|
+
def hotel_category
|
32
|
+
@hotel['content']['ext']['rich_info']['category']
|
33
|
+
end
|
34
|
+
def hotel_price
|
35
|
+
@hotel['content']['ext']['detail_info']['price']
|
36
|
+
end
|
37
|
+
def hotel_facility
|
38
|
+
@hotel['content']['ext']['rich_info']['inner_facility']
|
39
|
+
end
|
40
|
+
def hotel_short_comm
|
41
|
+
@hotel['content']['ext']['detail_info']['short_comm']
|
42
|
+
end
|
43
|
+
def hotel_review
|
44
|
+
reviews = []
|
45
|
+
@hotel['content']['ext']['review'].each do |r|
|
46
|
+
reviews << r if r['name']!='elong'
|
47
|
+
end
|
48
|
+
reviews
|
49
|
+
end
|
50
|
+
def hotel_image(uid)
|
51
|
+
url = HotelUri + "?qt=img&uid=#{uid}"
|
52
|
+
parsed_json = JSON.parse HTTParty.get url
|
53
|
+
parsed_json['images'].map{ |i| i['imgUrl']}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'httparty'
|
3
|
+
require 'uri'
|
4
|
+
module ESpider
|
5
|
+
module Front
|
6
|
+
module Baidu
|
7
|
+
module Map
|
8
|
+
module Hotel
|
9
|
+
class List
|
10
|
+
attr_reader :total
|
11
|
+
ListUri = "http://map.baidu.com/"
|
12
|
+
def initialize(city_cn)
|
13
|
+
@wd = URI.encode city_cn + '+' + '酒店'
|
14
|
+
@pn=1
|
15
|
+
url = ListUri+"?newmap=1&reqflag=pcmap&biz=1&qt=s&wd=#{@wd}&c=1&src=0&wd2=&sug=0&l=4&from=webmap&tn=B_NORMAL_MAP&nn=0&ie=utf-8"
|
16
|
+
@hotels = HTTParty.get url
|
17
|
+
@total = count_page_num
|
18
|
+
end
|
19
|
+
def next_page
|
20
|
+
return false if (@pn+1)*10 > @total
|
21
|
+
@pn += 1
|
22
|
+
url = "http://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&qt=s&wd=#{@wd}&c=1&src=0&sug=0&l=4&from=webmap&rn=10&pl_data_type=hotel&pn=#{@pn}"
|
23
|
+
p url
|
24
|
+
@hotels = HTTParty.get url
|
25
|
+
true
|
26
|
+
end
|
27
|
+
def list
|
28
|
+
parsed_json = JSON.parse @hotels
|
29
|
+
results = []
|
30
|
+
return nil if parsed_json['content'].nil?
|
31
|
+
parsed_json['content'].each do |hotel|
|
32
|
+
results << hotel
|
33
|
+
end
|
34
|
+
results
|
35
|
+
end
|
36
|
+
private
|
37
|
+
def count_page_num
|
38
|
+
parsed_json = JSON.parse @hotels
|
39
|
+
parsed_json['result']['total']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|