scraper_google_play 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/lib/scraper_google_play.rb +6 -1
- data/lib/scraper_google_play/app.rb +83 -0
- data/lib/scraper_google_play/base.rb +24 -0
- data/lib/scraper_google_play/category.rb +52 -0
- data/lib/scraper_google_play/search.rb +18 -0
- data/lib/scraper_google_play/version.rb +4 -1
- data/scraper_google_play.gemspec +2 -0
- metadata +34 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd442c04dbbd5e5472150aee957fc015bf4d6eb2
|
4
|
+
data.tar.gz: 3f2e546053bc811f4e63fc762d5e8cab3f640e30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c89b2283a1f5c11c4c7dc80de6c7538305b1eaf0a989fc14cddd70f2ca6036b459954d12d391f588c6b445b03567240e439906dc7694d01194f5bfd09eba7da
|
7
|
+
data.tar.gz: 779da175f04c9518bed67c673ad7972781946381e0194521c83ebfb0e0bc3ccb1ef219f6f87d2da21f8398c5d0a9eb643f6d8afd123da942ae1b06b340597c24
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/lib/scraper_google_play.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'mechanize' # and any other gems you need
|
2
|
+
require 'active_support/all'
|
3
|
+
require 'scraper_google_play/base'
|
4
|
+
require 'scraper_google_play/app'
|
5
|
+
require 'scraper_google_play/category'
|
6
|
+
require 'scraper_google_play/search'
|
2
7
|
|
3
8
|
module ScraperGooglePlay
|
4
9
|
def self.lorem
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class ScraperGooglePlay::App < ScraperGooglePlay::Base
|
2
|
+
attr_accessor :package_name, :app_name, :screen_shots, :developer, :address, :email, :title,
|
3
|
+
:genre_text, :genre_id, :version, :description, :android_version, :android_version_text,
|
4
|
+
:size, :vide, :score
|
5
|
+
|
6
|
+
def initialize(package_name, options = {})
|
7
|
+
|
8
|
+
@package_name = package_name
|
9
|
+
@agent = Mechanize.new
|
10
|
+
@query = {
|
11
|
+
id: package_name,
|
12
|
+
}.merge(options).to_query
|
13
|
+
|
14
|
+
unless exist?("#{ScraperGooglePlay::APPURL}?#{@query}")
|
15
|
+
@page = nil
|
16
|
+
else
|
17
|
+
@page = @agent.get("#{ScraperGooglePlay::APPURL}?#{@query}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def info
|
22
|
+
return {} unless @page
|
23
|
+
detailsInfo = @page.at('.details-info')
|
24
|
+
additionalInfo = @page.search('.details-section-contents')
|
25
|
+
|
26
|
+
mainGenre = detailsInfo.at('.category')
|
27
|
+
|
28
|
+
android_version_text = @page.at('.details-section-contents div.content[itemprop="operatingSystems"]').text().strip()
|
29
|
+
@app_info = {
|
30
|
+
name: name,
|
31
|
+
logo: logo,
|
32
|
+
screen_shots: screen_shots,
|
33
|
+
developer: detailsInfo.at('span[itemprop="name"]').text,
|
34
|
+
address: @page.at('.content.physical-address').try(:text),
|
35
|
+
email: @page.at('.content.contains-text-link .dev-link[href^="mailto:"]') ? @page.at('.content.contains-text-link .dev-link[href^="mailto:"]').attr('href').split(':')[-1] : nil ,
|
36
|
+
title: detailsInfo.at('.document-title').text.strip,
|
37
|
+
genre_text: mainGenre.text().strip,
|
38
|
+
genre_id: mainGenre.attr('href').split('/')[4],
|
39
|
+
version: @page.at('.details-section-contents div.content[itemprop="softwareVersion"]').text().strip(),
|
40
|
+
description: @page.at('.details-section-contents div[itemprop=description] div').text().gsub(/<\/p>/, '\n</p>'),
|
41
|
+
android_version_text: android_version_text,
|
42
|
+
android_version: normalizeAndroidVersion(android_version_text),
|
43
|
+
contentRating: @page.at('.details-section-contents div.content[itemprop="contentRating"]').text().strip(),
|
44
|
+
size: @page.at('.details-section-contents div.content[itemprop="fileSize"]').try(:text),
|
45
|
+
video: @page.at('.screenshots span.preview-overlay-container[data-video-url]') ? @page.at('.screenshots span.preview-overlay-container[data-video-url]').attr('data-video-url') : nil,
|
46
|
+
score: @page.at('.rating-box div.score').text().to_s.gsub(',', '.'),
|
47
|
+
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def similar_app
|
52
|
+
return nil unless @page
|
53
|
+
apps = []
|
54
|
+
recommendation = @page.at(".recommendation")
|
55
|
+
recommendation.search(".cards id-card-list .card.apps").each do |app|
|
56
|
+
apps << app.attr('data-docid')
|
57
|
+
end
|
58
|
+
apps
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def normalizeAndroidVersion (androidVersionText)
|
64
|
+
matches = androidVersionText.match(/^([0-9\.]+)[^0-9\.].+/)
|
65
|
+
|
66
|
+
if (!matches)
|
67
|
+
return 'VARY'
|
68
|
+
end
|
69
|
+
return matches[1];
|
70
|
+
end
|
71
|
+
|
72
|
+
def name
|
73
|
+
elem = @page.search(".id-app-title")
|
74
|
+
elem ? elem.first.text : ""
|
75
|
+
end
|
76
|
+
|
77
|
+
def logo
|
78
|
+
elem = @page.search(".main-content .apps img.cover-image")
|
79
|
+
elem ? "http:#{elem.first.attributes["src"].text}" : ""
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class ScraperGooglePlay::Base
|
2
|
+
|
3
|
+
def exist?(url)
|
4
|
+
uri = URI("#{url}")
|
5
|
+
status_code = Net::HTTP.get_response(uri).code
|
6
|
+
case status_code
|
7
|
+
when '200'
|
8
|
+
return true
|
9
|
+
when '404'
|
10
|
+
return false
|
11
|
+
else
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def list_packname_with_page(page)
|
17
|
+
return nil if page.nil?
|
18
|
+
apps = []
|
19
|
+
page.search('.id-card-list.card-list .card.apps').each do |elm|
|
20
|
+
apps << elm.attr('data-docid')
|
21
|
+
end
|
22
|
+
apps
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class ScraperGooglePlay::Category < ScraperGooglePlay::Base
|
2
|
+
|
3
|
+
def initialize(category_name)
|
4
|
+
@category_name = category_name.upcase
|
5
|
+
@agent = Mechanize.new
|
6
|
+
|
7
|
+
unless exist?("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}")
|
8
|
+
@page = nil
|
9
|
+
else
|
10
|
+
@page = @agent.get("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def all_app
|
15
|
+
return nil unless @page
|
16
|
+
list_packname_with_page(@page)
|
17
|
+
end
|
18
|
+
|
19
|
+
def topselling_paid
|
20
|
+
return nil unless @page
|
21
|
+
sub_page = @agent.get("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}/collection/topselling_paid")
|
22
|
+
list_packname_with_page(sub_page)
|
23
|
+
end
|
24
|
+
|
25
|
+
def topselling_free
|
26
|
+
return nil unless @page
|
27
|
+
sub_page = @agent.get("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}/collection/topselling_free")
|
28
|
+
list_packname_with_page(sub_page)
|
29
|
+
end
|
30
|
+
|
31
|
+
def topgrossing
|
32
|
+
return nil unless @page
|
33
|
+
sub_page = @agent.get("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}/collection/topgrossing")
|
34
|
+
list_packname_with_page(sub_page)
|
35
|
+
end
|
36
|
+
|
37
|
+
def topselling_new_paid
|
38
|
+
return nil unless @page
|
39
|
+
sub_page = @agent.get("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}/collection/topselling_new_paid")
|
40
|
+
list_packname_with_page(sub_page)
|
41
|
+
end
|
42
|
+
|
43
|
+
def topselling_new_free
|
44
|
+
return nil unless @page
|
45
|
+
sub_page = @agent.get("#{ScraperGooglePlay::CATEGORYURL}#{@category_name}/collection/topselling_new_free")
|
46
|
+
list_packname_with_page(sub_page)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ScraperGooglePlay::Search < ScraperGooglePlay::Base
|
2
|
+
|
3
|
+
def initialize(keyword)
|
4
|
+
@agent = Mechanize.new
|
5
|
+
@query = {
|
6
|
+
c: "apps",
|
7
|
+
q: keyword
|
8
|
+
}.to_query
|
9
|
+
@page = @agent.get("#{ScraperGooglePlay::SEARCHURL}?#{@query}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def apps
|
13
|
+
return nil unless @page
|
14
|
+
list_packname_with_page(@page)
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
data/scraper_google_play.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scraper_google_play
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nguyen Bach
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04
|
11
|
+
date: 2017-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.2.5
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.2.5
|
41
69
|
description: Write a longer description or delete this line.
|
42
70
|
email:
|
43
71
|
- trannguyenbach1992@gmail.com
|
@@ -52,6 +80,10 @@ files:
|
|
52
80
|
- bin/console
|
53
81
|
- bin/setup
|
54
82
|
- lib/scraper_google_play.rb
|
83
|
+
- lib/scraper_google_play/app.rb
|
84
|
+
- lib/scraper_google_play/base.rb
|
85
|
+
- lib/scraper_google_play/category.rb
|
86
|
+
- lib/scraper_google_play/search.rb
|
55
87
|
- lib/scraper_google_play/version.rb
|
56
88
|
- scraper_google_play-0.1.0.gem
|
57
89
|
- scraper_google_play.gemspec
|