compare_supermarkets 0.2.0 → 0.4.1
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/bin/console +0 -3
- data/bin/setup +1 -2
- data/config/environment.rb +0 -3
- data/lib/compare_supermarkets/cli.rb +9 -6
- data/lib/compare_supermarkets/product.rb +15 -1
- data/lib/compare_supermarkets/scraper.rb +39 -37
- data/lib/compare_supermarkets/supermarket.rb +40 -19
- data/lib/compare_supermarkets/version.rb +1 -1
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1791e9c3f62f3acd466b46d1c3a1cbce45f05788a1749e7f8c287d0ebf053abb
|
4
|
+
data.tar.gz: bf7badf710b0be6ad961db733eba0800933935245e8b8de93f45d6a8958f016b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd5dc190434e70a8c8df56d6b0d20908db2f55f977d7afe3509ea7b13799b3b4bda6012da2dcaff30cdf34ac4a3e78b1f48c2b1778b8b8d10edbb3a58fdb1b54
|
7
|
+
data.tar.gz: ec6273911b70374dca339d606a2588e71bd80c876561d4dece1f2065296f67ea0776056a82c84d95eb17a4e32e03e7bb5740e3fae2c6ef6e26e53b7ea5540885
|
data/bin/console
CHANGED
data/bin/setup
CHANGED
data/config/environment.rb
CHANGED
@@ -2,9 +2,6 @@ require 'pry'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'watir'
|
4
4
|
|
5
|
-
#gem install selenium-webdriver - required for watir to work
|
6
|
-
#brew install --cask chromedriver - required for watir to work
|
7
|
-
|
8
5
|
require_relative '../lib/compare_supermarkets/scraper'
|
9
6
|
require_relative '../lib/compare_supermarkets/product'
|
10
7
|
require_relative '../lib/compare_supermarkets/cli'
|
@@ -5,7 +5,7 @@ class CompareSupermarkets::CLI
|
|
5
5
|
puts ""
|
6
6
|
puts "Type q at any time to exit."
|
7
7
|
puts ""
|
8
|
-
puts "Would you like to compare prices between Coles and
|
8
|
+
puts "Would you like to compare prices between Coles and Woolworths (Y/N)"
|
9
9
|
input = gets.strip.downcase
|
10
10
|
puts ""
|
11
11
|
if input == "y"
|
@@ -42,23 +42,25 @@ class CompareSupermarkets::CLI
|
|
42
42
|
self.search_supermarkets(input)
|
43
43
|
puts ""
|
44
44
|
puts ""
|
45
|
-
if CompareSupermarkets::Product.count >
|
45
|
+
if CompareSupermarkets::Product.count > 20
|
46
46
|
puts ""
|
47
47
|
puts "Ooo, jeez, seems like we have a lot of results."
|
48
48
|
puts "We have #{CompareSupermarkets::Product.count} results for you."
|
49
49
|
puts "If you were a little more specific with your search"
|
50
50
|
puts "term, we would have less to sort through..."
|
51
51
|
puts ""
|
52
|
+
puts "If you still want to see all of these results, select N"
|
53
|
+
puts ""
|
52
54
|
change_search_term
|
53
55
|
elsif CompareSupermarkets::Product.count == 0
|
54
56
|
puts ""
|
55
|
-
puts "Ohhh man! Doesn't seem like
|
56
|
-
puts "that product."
|
57
|
+
puts "Ohhh man! Doesn't seem like any of these supermarkets"
|
58
|
+
puts "carry that product."
|
57
59
|
puts ""
|
58
60
|
change_search_term
|
59
61
|
else
|
60
62
|
puts ""
|
61
|
-
puts "Great! We have #{CompareSupermarkets::Product.count} items for you."
|
63
|
+
puts "Great! We have #{CompareSupermarkets::Product.count} items in stock for you."
|
62
64
|
puts ""
|
63
65
|
puts ""
|
64
66
|
puts ""
|
@@ -67,7 +69,8 @@ class CompareSupermarkets::CLI
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def search_supermarkets(input)
|
70
|
-
|
72
|
+
supermarkets = ["Coles", "Woolworths"]
|
73
|
+
CompareSupermarkets::Scraper.search_supermarkets(supermarkets, input)
|
71
74
|
end
|
72
75
|
|
73
76
|
def change_search_term
|
@@ -10,7 +10,13 @@ class CompareSupermarkets::Product
|
|
10
10
|
@unit_size = unit_size
|
11
11
|
@dollar_value = dollar_value
|
12
12
|
@cent_value = cent_value
|
13
|
-
@url = @supermarket.name == "Coles"
|
13
|
+
@url = if @supermarket.name == "Coles"
|
14
|
+
"https://shop.coles.com.au#{url}"
|
15
|
+
elsif @supermarket.name == "Woolworths"
|
16
|
+
"https://www.woolworths.com.au#{url}"
|
17
|
+
else
|
18
|
+
url
|
19
|
+
end
|
14
20
|
@@all << self
|
15
21
|
end
|
16
22
|
|
@@ -54,6 +60,14 @@ class CompareSupermarkets::Product
|
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
63
|
+
def self.iga_sorted_by_price
|
64
|
+
iga_items = self.all.select{|product| product.supermarket_name == "IGA"}
|
65
|
+
iga_items.sort_by! do |s|
|
66
|
+
price_to_sort = s.dollar_value + '.' + s.cent_value
|
67
|
+
price_to_sort.to_f
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
57
71
|
def self.clear_all
|
58
72
|
@@all.clear
|
59
73
|
end
|
@@ -6,56 +6,58 @@ class CompareSupermarkets::Scraper
|
|
6
6
|
@search_term = search_term
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.search_supermarkets(search_term)
|
10
|
-
|
11
|
-
|
9
|
+
def self.search_supermarkets(supermarkets, search_term)
|
10
|
+
supermarkets.each do |supermarket|
|
11
|
+
Kernel.const_get("CompareSupermarkets::#{supermarket}Scraper").search_browser(search_term)
|
12
|
+
end
|
12
13
|
end
|
13
14
|
|
14
|
-
def self.
|
15
|
+
def self.handle_waiting(supermarket, class_name, all_products, search, check)
|
15
16
|
browser = Watir::Browser.new :chrome
|
16
|
-
browser.goto("https://shop.coles.com.au/a/national/everything/search/#{search_term}")
|
17
17
|
begin
|
18
|
-
|
18
|
+
browser.goto(search)
|
19
|
+
js_doc = browser.element(class: class_name).wait_until(&:present?)
|
19
20
|
rescue
|
20
|
-
puts "
|
21
|
-
puts ""
|
22
|
-
puts "Let's check Woolworths"
|
23
|
-
puts ""
|
21
|
+
puts "This product cannot be found"
|
24
22
|
puts ""
|
25
23
|
else
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
if product.css(
|
30
|
-
|
31
|
-
coles.add_product(product)
|
24
|
+
new_supermarket = Kernel.const_get("CompareSupermarkets::#{supermarket}").new(supermarket)
|
25
|
+
products = Nokogiri::HTML(js_doc.inner_html)
|
26
|
+
products.css(all_products).each do |product|
|
27
|
+
if product.css(check).text != ""
|
28
|
+
new_supermarket.add_product(product)
|
32
29
|
end
|
33
30
|
end
|
31
|
+
if new_supermarket.products.count == 0
|
32
|
+
puts "#{supermarket} do not have this item"
|
33
|
+
end
|
34
34
|
ensure
|
35
35
|
browser.close
|
36
36
|
end
|
37
37
|
end
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
woolworths_products = Nokogiri::HTML(woolworths_js_doc.inner_html)
|
48
|
-
woolworths_all_products = woolworths_products.css(".shelfProductTile-content")
|
49
|
-
woolworths_all_products.each do |product|
|
50
|
-
if product.css(".shelfProductTile-descriptionLink").text != ""
|
51
|
-
if product.css(".unavailableSection.width-full.ng-star-inserted").empty?
|
52
|
-
woolworths = CompareSupermarkets::Supermarket.new("Woolworths")
|
53
|
-
woolworths.add_product(product)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
ensure
|
58
|
-
browser.close
|
59
|
-
end
|
40
|
+
class CompareSupermarkets::ColesScraper < CompareSupermarkets::Scraper
|
41
|
+
|
42
|
+
def self.search_browser(search_term)
|
43
|
+
search = "https://shop.coles.com.au/a/national/everything/search/#{search_term}"
|
44
|
+
class_name = "products"
|
45
|
+
all_products = ".product"
|
46
|
+
check = ".product-name"
|
47
|
+
self.handle_waiting('Coles', class_name, all_products, search, check)
|
60
48
|
end
|
49
|
+
|
61
50
|
end
|
51
|
+
|
52
|
+
class CompareSupermarkets::WoolworthsScraper < CompareSupermarkets::Scraper
|
53
|
+
|
54
|
+
def self.search_browser(search_term)
|
55
|
+
search = "https://www.woolworths.com.au/shop/search/products?searchTerm=#{search_term}"
|
56
|
+
all_products = ".shelfProductTile-content"
|
57
|
+
class_name = "layoutWrapper"
|
58
|
+
check = ".shelfProductTile-descriptionLink"
|
59
|
+
self.handle_waiting('Woolworths', class_name, all_products, search, check)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
@@ -9,25 +9,12 @@ class CompareSupermarkets::Supermarket
|
|
9
9
|
@products = []
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
product.css(".product-image-link").attribute('href'),
|
19
|
-
product.css(".dollar-value").text,
|
20
|
-
product.css(".cent-value").text.delete_prefix('.'))
|
21
|
-
else
|
22
|
-
new_product = CompareSupermarkets::Product.new(self,
|
23
|
-
product.css(".shelfProductTile-descriptionLink").text,
|
24
|
-
product.css(".shelfProductTile-cupPrice.ng-star-inserted").text.delete_prefix(' $').chomp(" "),
|
25
|
-
product.css(".shelfProductTile-descriptionLink").text.split(" ").last,
|
26
|
-
product.css(".shelfProductTile-descriptionLink").attribute('href').value,
|
27
|
-
product.css(".price-dollars").text,
|
28
|
-
product.css(".price-cents").text)
|
29
|
-
end
|
30
|
-
@products << new_product
|
12
|
+
def self.all
|
13
|
+
@@all
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.out_of_stock
|
17
|
+
@out_of_stock.count
|
31
18
|
end
|
32
19
|
|
33
20
|
def products
|
@@ -38,4 +25,38 @@ class CompareSupermarkets::Supermarket
|
|
38
25
|
@@all.clear
|
39
26
|
end
|
40
27
|
|
28
|
+
end
|
29
|
+
|
30
|
+
class CompareSupermarkets::Coles < CompareSupermarkets::Supermarket
|
31
|
+
|
32
|
+
def add_product(product)
|
33
|
+
supermarket = self
|
34
|
+
name = product.css(".product-name").text
|
35
|
+
price = product.css(".package-price").text.delete_prefix('$').gsub('per', '/')
|
36
|
+
unit_size = product.css(".package-size.accessibility-inline").text.chomp(' ')
|
37
|
+
url = product.css(".product-image-link").attribute('href')
|
38
|
+
dollar_value = product.css(".dollar-value").text
|
39
|
+
cent_value = product.css(".cent-value").text.delete_prefix('.')
|
40
|
+
if dollar_value != "0" && cent_value != "0"
|
41
|
+
new_product = CompareSupermarkets::Product.new(supermarket, name, price, unit_size, url, dollar_value, cent_value)
|
42
|
+
@products << new_product
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class CompareSupermarkets::Woolworths < CompareSupermarkets::Supermarket
|
48
|
+
|
49
|
+
def add_product(product)
|
50
|
+
supermarket = self
|
51
|
+
name = product.css(".shelfProductTile-descriptionLink").text
|
52
|
+
price = product.css(".shelfProductTile-cupPrice.ng-star-inserted").text.delete_prefix(' $').chomp(" ")
|
53
|
+
unit_size = product.css(".shelfProductTile-descriptionLink").text.split(" ").last
|
54
|
+
url = product.css(".shelfProductTile-descriptionLink").attribute('href').value
|
55
|
+
dollar_value = product.css(".price-dollars").text
|
56
|
+
cent_value = product.css(".price-cents").text
|
57
|
+
if dollar_value != "0" && cent_value != "0"
|
58
|
+
new_product = CompareSupermarkets::Product.new(supermarket, name, price, unit_size, url, dollar_value, cent_value)
|
59
|
+
@products << new_product
|
60
|
+
end
|
61
|
+
end
|
41
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: compare_supermarkets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Berger Howes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,33 +53,33 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.10.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
76
|
-
type: :
|
75
|
+
version: 1.10.8
|
76
|
+
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.10.8
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: watir
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 6.19.1
|
90
|
-
type: :
|
90
|
+
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 3.142.7
|
104
|
-
type: :
|
104
|
+
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|