Skip to content

Instantly share code, notes, and snippets.

@doomspork
Last active December 14, 2015 13:29
Show Gist options
  • Save doomspork/5094036 to your computer and use it in GitHub Desktop.
Save doomspork/5094036 to your computer and use it in GitHub Desktop.
JRuby script to pull iOS app ranking data from AppAnnie.com. Must be passed a file containing an app name, internal id (optional), and the store id per new line. Using System.out to print results. Example usage: ruby ranking.rb seed_file.txt > ranking.txt
require 'java'
require 'net/http'
require 'uri'
require 'nokogiri'
System = java.lang.System
java_import java.util.concurrent.Executors
@executor = Executors.newFixedThreadPool 3
class TooManyRedirects < StandardError; end
def ratings_from_body(body)
ratings = {:current => {}, :all => {}}
document = Nokogiri::HTML(body)
rating_container = document.at_css('div.app_slide_container')
unless rating_container.nil?
current_el = rating_container.at_css('div#r_current')
unless current_el.nil?
strongs = current_el.css('strong')
rating = strongs[0].content.to_f
count = strongs[1].content.to_i
ratings[:current] = {:rating => rating, :count => count}
end
all_el = rating_container.at_css('div#r_all')
unless all_el.nil?
strongs = all_el.css('strong')
rating = strongs[0].content.to_f
count = strongs[1].content.to_i
ratings[:all] = {:rating => rating, :count => count}
end
end
ratings
end
def get_body(url, redirects = 5)
uri = URI(url)
response = Net::HTTP.get_response(uri)
if response.kind_of? Net::HTTPRedirection
raise TooManyRedirects if redirects == 0
return get_body(response['location'], redirects - 1)
end
response.body
end
def request_ratings(store_id, details = {})
app_id = details[:app_id] || ""
app_name = details[:name] || ""
@executor.submit do
body = nil
begin
url = "http://www.appannie.com/app/ios/#{store_id}"
#System.out.println("#Request! #{url}")
body = get_body url
rescue TooManyRedirects
System.err.println("#Timeout! #{store_id}")
end
unless body.nil?
ratings = ratings_from_body(body)
current_rating = ratings[:current][:rating] || 0
current_count = ratings[:current][:count] || 0
all_rating = ratings[:all][:rating] || 0
all_count = ratings[:all][:count] || 0
System.out.printf("%s,%s,%s,%s,%s,%s\n", app_name, app_id, current_rating, current_count, all_rating, all_count)
end
end
end
lines = File.open(ARGV[0], 'rb').read.split("\n")
apps = lines.map { |v| v.split(",")}
apps.each do |details|
name = details[1]#['name']
app_id = details[2]#['app_id']
id = details[0]#['store_id']
request_ratings id, {:name => name, :app_id => app_id}
end
#request.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.12011-10-16 20:23:00'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment