class AndroidReviews

Constants

DEFAULT_USER_AGENT
URL
VERSION

Attributes

language[RW]
pages_per_minute[RW]
review_sort_order[RW]
review_type[RW]
user_agent[RW]

Public Class Methods

new(app_id, pages_per_minute: 6, language: 'en', user_agent: DEFAULT_USER_AGENT) click to toggle source
# File lib/android_reviews.rb, line 13
def initialize(app_id, pages_per_minute: 6, language: 'en', user_agent: DEFAULT_USER_AGENT)
  @app_id            = app_id
  @pages_per_minute  = pages_per_minute
  @language          = language
  @user_agent        = user_agent
  @review_sort_order = 0
  @review_type       = 0
end

Public Instance Methods

each_review() { |review| ... } click to toggle source
# File lib/android_reviews.rb, line 22
def each_review
  count = 0
  current_page = 0

  while body = fetch(current_page)
    body.gsub!(/^\)\]\}\'/, '')
    parsed = JSON.parse(body)
    html = parsed[0][2]
    html_doc = Nokogiri::HTML(html)

    html_doc.css('.single-review').each do |node|
      count += 1
      review = review_from_node(node)
      yield review
    end # review loop

    current_page += 1
    throttle_sleep
  end # page loop

  count
end
reviews() click to toggle source
# File lib/android_reviews.rb, line 45
def reviews
  reviews = []
  each_review do |r|
    reviews << r
  end
  reviews
end

Protected Instance Methods

fetch(page) click to toggle source
# File lib/android_reviews.rb, line 54
def fetch(page)
  headers = {
    "origin" => "https://play.google.com",
    "accept-encoding" =>  "gzip, deflate",
    "accept-language" =>  "en-US,en;q=0.8",
    "user-agent" =>  @user_agent,
    "content-type" =>  "application/x-www-form-urlencoded;charset=UTF-8",
    "accept" =>  "*/*",
    "referer" =>  "https://play.google.com/store/apps/details?id=#{@app_id}&hl=#{@language}",
    "authority" =>  "play.google.com"
  }

  data = "reviewType=#{@review_type}&pageNum=#{page}&id=#{@app_id}&reviewSortOrder=#{@review_sort_order}&xhr=1&hl=#{@language}"

  response = nil
  begin
    response = RestClient.post URL, data, headers
    response.code == 200 ? response.body : nil
  rescue RestClient::Found
    raise ThrottledError
    nil
  end
end
review_from_node(node) click to toggle source
# File lib/android_reviews.rb, line 78
def review_from_node(node)
  {
    author_name: node.css('.author-name a').text.strip,
    review_date: Date.parse(node.css('.review-date').text.strip),
    rating:      node.css('.review-info-star-rating .tiny-star').attr('aria-label').text.match(/([1-5])/)[0].strip,
    title:       node.css('.review-title').text.strip,
    body:        node.search('.review-body').xpath('text()').text.strip,
    avatar_url:  node.css('.responsive-img-hdpi .author-image').attr('style').text.match(/\((.*)\)/)[1]
  }
end
throttle_sleep() click to toggle source
# File lib/android_reviews.rb, line 89
def throttle_sleep
  sleep(60 / pages_per_minute.to_f) if pages_per_minute
end