ちまたで見られるGooglePlayのレビューを取得する記事の多くは、GetリクエストからHTMLのページを取得、その要素から必要なものを取得するという方法でした。
ただし、GooglePlayはデフォルトではレビューの並びが新着順ではありません。
一方、私は新着順の情報が欲しい。
そこで、簡単なスクリプトを作ってみました。
すんなりいくかと思っていたら、Net::HTTPから取得しいたNet::HTTPResponseのbodyをNokogiriに読み込ませていたのですが、うまくパースされない。
そこで解決に至ったまでの作業を備忘録として残しておきます。
出会った問題
Nokogiriに読み込ませるresponse.bodyに、Unicodeエスケープが施されて、
< >
の記号が
u003e u003c
に置き換わっていて、Nokogiri::HTMLに読み込ませて期待するNokogiri::XMLが得られなかった。
解決策
解決策というか、単にUnicodeエスケープをデコードしたものをNokogiri::HTTPに与えることにしました。
response.gsub!(/u([0-9a-f]{4})/) {
[$1.hex].pack("U")
}
以下、今回の作業で作成したスクリプトです。
# coding: utf-8
require 'rubygems'
require 'nokogiri'
require 'net/http'
require 'active_support/core_ext/string'
# Your package name
APPLICATION_ID = 'com.android.chrome'
MAX_POST = 20 # up to 20
GOOGLE_PLAY_HOT = 'https://play.google.com'
GOOGLE_PLAY_URL = '/store/getreviews'
GOOGLE_PLAY_REVIEW_REQUEST = "id=#{APPLICATION_ID}&xhr=1&reviewSortOrder=0&reviewType=1&pageNum=0"
def get_google_play_reviews_upto(post_count)
return puts "You can require review post up to 20." if post_count > MAX_POST
uri = URI.parse("#{GOOGLE_PLAY_HOT}#{GOOGLE_PLAY_URL}")
data = GOOGLE_PLAY_REVIEW_REQUEST
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
# obtain response from google play
response = http.post(uri.path, data).body.split("n")[2]
# convert unicode escaped string to "<" and ">"
response.gsub!(/u([0-9a-f]{4})/) {
[$1.hex].pack("U")
}
review_html = Nokogiri::HTML(response, nil, 'UTF-8')
(0..post_count-1).each.map do |node_num|
<<-EOS.strip_heredoc.squish
#{review_html.css('span."review-date"')[node_num].inner_text}:
#{review_html.css('div."review-body"')[node_num].children[1].inner_text}
#{review_html.css('div."review-body"')[node_num].children[2].inner_text}
EOS
end
end