Skip to content

Instantly share code, notes, and snippets.

@mcoms
Last active January 1, 2016 23:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcoms/8220583 to your computer and use it in GitHub Desktop.
Save mcoms/8220583 to your computer and use it in GitHub Desktop.
Where's the best place to buy 7?
require 'nokogiri'
require 'open-uri'
require 'json'
doc = Nokogiri::HTML(open('http://www.mysupermarket.co.uk/asda-compare-prices/Spirits/Havana_Club_Rum_Anejo_7_Year_Old_700ml.html'))
prices = doc.css('#PriceComparison .StoreDiv').map {|c| { name: c.css('.ImgSpan img').first['alt'], cheapest: c['class'].include?('Cheapest'), price: c.css('.Price>span.priceClass, .Price>span.Offer').text.strip } }
# => [{:name=>"ASDA", :cheapest=>true, :price=>"£18.00"},
# {:name=>"Tesco", :cheapest=>false, :price=>"£23.30"},
# {:name=>"Ocado", :cheapest=>false, :price=>"£23.30"},
# {:name=>"Waitrose", :cheapest=>false, :price=>"£23.30"},
# {:name=>"Sainsbury's", :cheapest=>false, :price=>"£26.00"},
# {:name=>"Aldi", :cheapest=>false, :price=>""}]
cheapest = prices.find {|p| p[:cheapest] }
# => {:name=>"ASDA", :cheapest=>true, :price=>"£18.00"}
puts "The cheapest place for 7 is #{cheapest[:name]} at #{cheapest[:price]}."
breakdown = prices.reject {|p| p[:price] == '' }.group_by {|p| p[:price] }.sort
# => [["£18.00", [{:name=>"ASDA", :cheapest=>true, :price=>"£18.00"}]],
# ["£23.30",
# [{:name=>"Tesco", :cheapest=>false, :price=>"£23.30"},
# {:name=>"Ocado", :cheapest=>false, :price=>"£23.30"},
# {:name=>"Waitrose", :cheapest=>false, :price=>"£23.30"}]],
# ["£26.00", [{:name=>"Sainsbury's", :cheapest=>false, :price=>"£26.00"}]]]
puts "Then it's:"
breakdown.each {|b| puts " #{b[0]} at #{b[1].map {|p| p[:name] }.join(', ')}." }
# The cheapest place for 7 is ASDA at £18.00.
# Then it's:
# £18.00 at ASDA.
# £23.30 at Tesco, Ocado, Waitrose.
# £26.00 at Sainsbury's.
doc.css('#PriceComparison script').find {|e| e.text =~ /ProductPriceGraph.HandleGraph\((.+)\)/ }
graph = JSON.parse $1
# => {"First"=>-1.48571428571429,
# "Max"=>24.36,
# "Last"=>62.4,
# "ElementId"=>"PriceGraph148894S",
# "IsSavvy"=>false,
# "Today"=>[[52, 18, "<span>02/01/2014</span> £18.00", "Today"]],
# "Min"=>16.94,
# "UseLazyLoad"=>false,
# "Prices"=>
# [[0, 21.8, "<span>06/01/2013</span> £21.80"],
# [1, 21.8, "<span>13/01/2013</span> £21.80"],
# [2, 21.8, "<span>20/01/2013</span> £21.80"],
# ...
# [50, 20, "<span>22/12/2013</span> £20.00"],
# [51, 23.3, "<span>29/12/2013</span> £23.30"],
# [52, 18, "<span>02/01/2014</span> £18.00"]]}
puts "52-week price history:"
graph['Prices'].each {|p| puts " #{Nokogiri::HTML(p.last).text}" }
# 52-week price history:
# 06/01/2013 £21.80
# 13/01/2013 £21.80
# 20/01/2013 £21.80
# ...
# Note price history is for the current supermarket as per the open(...) call.
# In this case ASDA (.../asda-compare-prices/...).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment