Is there a way to show all ratings in Play?
You can see some ratings ordered descending:
but for hundreds of thousands of reviews it's not that feasible cause you can only read the 5-star ratings this way.
Is there another better way to view the ratings?
maybe this is possible with Greasemonkey?
Best Answer
Equally frustrated by the lack of decent filtering/sorting options in Google Play, and inspired by your suggestion that a Greasemonkey script could solve the problem, I decided to write one, which I have uploaded to https://greasyfork.org/en/scripts/24667-google-play-review-rating-filter. It adds five checkboxes to app pages on play.google.com which allow you to filter for reviews with specific star ratings. I’ve tested it with Greasemonkey and Unified Script Injector in Firefox, and Tampermonkey in Chrome.
Rather than reproduce the entire script here, I’ll describe the approach taken for those who may be interested. TL;DR: If you just want the solution, install the appropriate browser add-on and download the user script from the link above. Note that if you want to use it on your Android device itself, you’ll probably need to use Firefox with the USI add-on (and also select Request Desktop Site from the menu), as most other Android browsers do not support add-ons or user scripts and Greasemonkey currently does not work in Firefox for Android – it will not work in the Google Play app.
As you flick through reviews, GP (Google Play) loads data for more reviews via AJAX requests to the URL
/store/getreviews
using the HTTPPOST
method. So by hooking these AJAX calls, it is possible to modify the data returned to GP.XMLHttpRequest.prototype.open
can be replaced with a function which will call the original, but first, if the request is for review data, modify the XHR (XMLHttpRequest
) object so that thePOST
request body can be captured and the response modified. Asend
property can be assigned to the XHR object as a function which will store thePOST
data before calling the original. Theonreadystatechange
property can be assigned as a function which will modify the response before calling the function assigned by GP to this property. As GP will assignonreadystatechange
after this,Object.defineProperty
would need to be used to redefine the property so that the value GP sets is stored rather than actually being assigned to the internal property. And as theresponseText
property is read-only,Object.defineProperty
would be needed to change its value.The data returned by GP is in JSON format, though has a few characters of junk at the start which should be faithfully reproduced in any modified data.
The following code demonstrates this, and will output to the browser’s developer console window the request body and response data (though doesn’t actually modify it):
The data returned by GP comprises an array of one element which is an array of four elements as follows:
"ecr"
;1
if there are more reviews,2
if this is the last ‘page’ of reviews,3
if an error occurred;pageNum
parameter in the POST request body.The HTML can be modified to remove reviews (and any associated developer reply) with star ratings other than those of interest. The reviews match the selector
div.single-review
and have a descendant matchingdiv.current-rating
with an inline style where the CSS width property is a percentage corresponding to the rating (20%
for 1 star,40%
for 2 stars, etc.). Developer replies match the selectordiv.developer-reply
and are siblings immediately following the review.Adding checkboxes to the UI to allow choosing which star-ratings of reviews to show is fairly straightforward. However, when their selections are changed, the reviews need to be fetched afresh. Changing the sort order causes this to occur, as does even selecting the same sort order as before. So to achieve this automatically, whenever a checkbox is changed, a
click
event can be triggered on the currently selected sort order element, which can be found with a selector of.id-review-sort-filter .dropdown-child.selected
. When an app page on GP is initially loaded, the first page of reviews are already included and are not loaded via AJAX, but as long as the checkboxes are all initially checked, that won’t matter.Sometimes a page of (40) reviews won’t contain any with a desired rating. If no elements exist in the returned HTML, GP won’t request any more pages. So to cater for this, it would be necessary to fetch additional pages of reviews (via the same AJAX API, but modifying the
pageNum
parameter) until there are some reviews to return. And for subsequent pages, thepageNum
parameter would need translating to account for this.When the selected sort order is ‘Rating’, there could be many pages of 5 star reviews before any with a desired rating. Repeatedly fetching and discarding pages and pages of reviews would be inefficient (and could trigger a temporary IP block by Google). In this case, when the
reviewSortOrder
parameter is1
, a binary search can be employed to much more quickly find the next page with reviews to return. A page element matching the selectorspan.reviews-num
can be inspected to find the total number of reviews and thus determine an upper page number bound. Though, as it turns out currently, requests for pages beyond page 111 receive an HTTP 400 response.