Amazon Product Advertising API: Get Average Customer Rating - amazon-web-services

When using Amazon's web service to get any product's information, is there a direct way to get the Average Customer Rating (1-5 stars)? Here are the parameters I'm using:
Service=AWSECommerceService
Version=2011-08-01
Operation=ItemSearch
SearchIndex=Books
Title=A Game of Thrones
ResponseGroup=Large
I would expect it to have a customer rating of 4.5 and total reviews of 2177. But instead I get the following in the response.
<CustomerReviews><IFrameURL>http://www.amazon.com/reviews/iframe?...</IFrameURL></CustomerReviews>
Is there a way to get the overall customer rating, besides for reading the <IFrameURL/> value, making another HTTP request for that page of reviews, and then screen scraping the HTML? That approach is fragile since Amazon could easily change the reviews page structure which would bust my application.

You can scrape from here. Just replace the asin with what you need.
http://www.amazon.com/gp/customer-reviews/widgets/average-customer-review/popover/ref=dpx_acr_pop_?contextId=dpx&asin=B000P0ZSHK

As far as i know, Amazon changed it's API so its not possible anymore to get the reviewrank information. If you check this Link the note sais:
As of November 8, 2010, only the iframe URL is returned in the request
content.
However, testing with the params you used to get the Iframe it seems that now even the Iframe dosn't work anymore. Thus, even in the latest API Reference in the chapter "Motivating Customers to Buy" the part "reviews" is compleatly missing.
However: Since i'm also very interested if its still possible somehow to get the reviewrank information - maybe even not using amazon API but a competitors API to get review rank informations - i'll set up a bounty if anybody can provide something helpful on that. Bounty will be set in this topic in two days.

You can grab the iframe review url and then use css to position it so only the star rating shows. It's not ideal since you're not getting raw data, but it's an easy way to add the rating to your page.
Sample of this in action - http://spamtech.co.uk/positioning-content-inside-an-iframe/

Here is a VBS script that would scrape the rating. Paste the code below to a text file, rename it to Test.vbs and double click to run on Windows.
sAsin = InputBox("What is your ASIN?", "Amazon Standard Identification Number (ASIN)", "B000P0ZSHK")
if sAsin <> "" Then
sHtml = SendData("http://www.amazon.com/gp/customer-reviews/widgets/average-customer-review/popover/ref=dpx_acr_pop_?contextId=dpx&asin=" & sAsin)
sRating = ExtractHtml(sHtml, "<span class=""a-size-base a-color-secondary"">(.*?)<\/span>")
sReviews = ExtractHtml(sHtml, "<a class=""a-size-small a-link-emphasis"".*?>.*?See all(.*?)<\/a>")
MsgBox sRating & vbCrLf & sReviews
End If
Function ExtractHtml(sHtml,sPattern)
Set oRegExp = New RegExp
oRegExp.Pattern = sPattern
oRegExp.IgnoreCase = True
Set oMatch = oRegExp.Execute(sHtml)
If oMatch.Count = 1 Then
ExtractHtml = Trim(oMatch.Item(0).SubMatches(0))
End If
End Function
Function SendData(sUrl)
Dim oHttp 'As XMLHTTP30
Set oHttp = CreateObject("Msxml2.XMLHTTP")
oHttp.open "GET", sUrl, False
oHttp.send
SendData = Replace(oHttp.responseText,vbLf,"")
End Function

Amazon has completely removed support for accessing rating/review information from their API. The docs mention a Response Element in the form of customer rating, but that doesn't work either.
Google shopping using Viewpoints for some reviews and other sources

This is not possible from PAPI. You either need to scrape it by yourself, or you can use other free/cheaper third-party alternatives for that.
We use the amazon-price API from RapidAPI for this, it supports price/rating/review count fetching for up to 1000 products in a single request.

Related

How to get Zomato restaurant ID using restaurant link?

I want to get details of a restaurant in Zomato. I have it's link as the input (https://www.zomato.com/mumbai/fantasy-the-cake-shop-kalyan?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1). By browsing the documentation of Zomato APIs, I didn't found a way to get it.
I tried searching for the restaurant using search API but it returns many results.
Any help will be appreciated
It's a two-step process:
Find out restaurant's city id, in your case, Mumbai's city id through the /cities API. It's a simple query search.
Use the city id from the above API call in the /search API, like, https://developers.zomato.com/api/v2.1/search?entity_type=city&entity_id=3&q=fantasy%20the%20cake%20shop%20kalyan
This would give all the basic information about a restaurant.
View the page's source and search for window.RES_ID
I had the same issue as you described. This Zomato's API approach is at least odd. It's almost immposible to GET any information about restaurant if you don't know res_id in advance and that's not possible to parse since Zomato will deny access.
This worked for me:
Obtain user-key from Zomato API Credentials (https://developers.zomato.com/api)
Search restaurant url via API (https://developers.zomato.com/api/v2.1/search?entity_id=84&entity_type=city&q=RESTAURANT_URL&category=7%2C9). The more specific you will be, the better results you'll get (This url is specified by city to Prague (ID = 84) and categories Daily menus (ID = 7) and Lunch (ID = 9). If there is possibility do specify city, category or cuisine, it helps, but should't be necessary. Don't forget to define GET method in headers.
Loop or filter through json results and search for the wanted url. You might need to use method valueOf() to search for the same url. Be careful, you might need to add "?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1" at the end of your wanted url so it has the same format. Check that through Zomato API Documentation page.
for (i in body.restaurants) {
var url_wanted = restaurant_url + '?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1'
var url_in_json = body.restaurants[i].restaurant.url;
if (url_wanted.valueOf() == url_in_json.valueOf()) {
var restaurant_id = body.restaurants[i].restaurant.id;
}
console.log('Voala! We have res_id:' + restaurant_id);
}
There you have it. It could be easier though.
Hope it helps!
once you have the url of the rseraunt's page you can simply look for a javascript object attribute named "window.RES_ID" and further use it in the api call.

Tweepy API search doesn't have keyword

I am working with Tweepy (python's REST API client) and I'm trying to find tweets by several keywords and without url included in tweet.
But search results are not up to our satisfaction. Looks like query has erros and was stopped. Additionally we had observed that results were returned one-by-one not (as previously) in bulk packs of 100.
Could you please tell me why this search does not work properly?
We wanted to get all tweets mentioning 'Amazon' without any URL links in the text.
We used search shown below. Search results were still containing tweets with URLs or without 'Amazon' keyword.
Could you please let us know what we are doing wrong?
auth = tweepy.AppAuthHandler(consumer_key, consumer_secret)
api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
searchQuery = 'Amazon OR AMAZON OR amazon filter:-links' # Keyword
new_tweets = api.search(q=searchQuery, count=100,
result_type = "recent",
max_id = sinceId,
lang = "en")
The minus sign should be put before "filter", not before "links", like this:
searchQuery = 'Amazon OR AMAZON OR amazon -filter:links'
Also, I doubt that the count = 100 option is a valid one, since it is not listed on the API documentation (which may not be very up-to-date, though). Try to replace that with rpp = 100 to get tweets in bulk packs.
I am not sure why some of the tweets you find do not contain the "Amazon" keyword, but a possibility is that "Amazon" is contained within the username of the poster. I do not know if you can filter that directly in the query, or even if you would want to filter it, since it would mean you would reject tweets from the official Amazon accounts. I would suggest that, for each tweet the query returns, you check it to make sure it does contain "Amazon".

Using cookies to filter data in Google Analytics

I am trying to filter Google Analytics data for my company site based on a cookie. I don't want to track internal traffic, but I can't just filter based on an IP address range because there are some internal users who we want to still track. I have some pretty simple code for adding a cookie, but I am just not sure where to add the code. I am really new to cookies, and couldn't find anything online that was clear on how to actually add or use the cookie.
<html>
<head>
<title>Remove My Internal Traffic from Google Analytics</title>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-YY']);
_gaq.push(['_setVar','employee']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
So my question is, where does this code actually go? Thanks for helping out my novice skills with cookies.
Do not use setVar (this is deprecated), use _setCustomVar:
_setCustomVar(index, name, value, opt_scope)
The call goes before the _trackPageview Call.
There are five custom vars in standard GA (50 in premium), that's "index". 'Name' and 'value' should be clear.
CustomVars are either valid for the current page, for the session or for the visitor (in the last case they are valid until the visitors clears the cookies in his browsers unless he waits six months before he visits you site again).
Like every instruction with the asynonchronous GA code this is "pushed" on the gaq-Array, so the correct call would be:
_gaq.push(['_setCustomVar',
1, // This custom var is set to slot #1. Required parameter.
'Items Removed', // The name acts as a kind of category for the user activity. Required parameter.
'Yes', // This value of the custom variable. Required parameter.
2 // Sets the scope to session-level. Optional parameter.
]);
which is taken from the Google documentation here:
https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingCustomVariables#setup.
I still maintain that for your use case the opt-out plugin is the better solution.
UPDATE: Thinking about it I don't think you need setCustomVar or custom cookies at all. Have your employees go to your website via a link like:
mywebsite.com?utm_source=allyourbasearebelongtous
Then go to the profile settings and create a custom filter, set to exclude, filter field "campaign source" , filter pattern "allyourbasearebelongtous" (or whatever name you gave to your campaign parameter).
This uses also a cookie (the standard google cookie) but does not need any custom code at all. The campaign source parameter is valid until they visit another campaign geared towards your site, so if somebody wants to test the GA code they need to delete their cookies or use incognito mode (but that't not different from setting a custom cookie or setCustomVar-methods).

Display name & picture knowing ID

I was looking to find an answer to my question, but so far I got this:
https://graph.facebook.com/the_user_id?fields=name,picture
I need to be able to display/print first,last name and picture of a set list of users for which I know their ID. What code is required to get this data and then to publish it on a php/html page? Of course, this will means that if I want to show 10 users, I will input 10 different IDs (read smtg about an array list?). Notice that I DO NOT require for this to work for the current user.
Thanks in advance for your replies.
You need to use file_get_contents ( http://uk3.php.net/file_get_contents ) or curl in php and issue a request to the url such as follows:
https://graph.facebook.com/?ids=id1,id2,id3&fields=name,picture
(replacing id1,id2 with your ids)
this will then return you a json object. You then need to decode ( http://uk3.php.net/json_decode ) and loop through this and access the information
this should get you started
// people array uses the users id as the key and the dessert as the value. The id is then used in the query to facebook to select the corresponding value from this array
$people = array("id1"=>"favourite "dessert", "id2"=>"favourite dessert", "id3"=>"apple pie");
$json = file_get_contents('https://graph.facebook.com/?ids=id1,id2,id3&fields=id,name,picture');
$json = json_decode($json);
foreach($json as $key=>$person){
echo '<p><img src="'.$person->picture.'" alt="'.$person->name.'" />';
echo $person->name.'\'s favourite dessert is '.$people[$person->id'];
echo '</p>';
}
I've batched the requests here, alternatively you could perform 10 separate queries for each user, but that would be a bit pointless and inefficient
The easiest way is with an FQL query:
SELECT first_name, last_name, pic, uid FROM user WHERE uid IN
(Known_ID_1, Known_ID_2, ... Known_ID_n)
The easiest, if you're using PHP is to install the PHP SDK, though you can also make a call directly to https://graph.facebook.com/fql?q=URL_ENCODED_QUERY

How to obtain longitude and latitude for a street address programmatically (and legally)

Supposedly, it is possible to get this from Google Maps or some such service. (US addresses only is not good enough.)
The term you're looking for is geocoding and yes Google does provide this service.
New V3 API: http://code.google.com/apis/maps/documentation/geocoding/
Old V2 API: http://code.google.com/apis/maps/documentation/services.html#Geocoding
In addition to the aforementioned Google geocoding web service, there is also a competing service provided by Yahoo. In a recent project where geocoding is done with user interaction, I included support for both. The reason is I have found that, especially outside the U.S., their handling of more obscure locations varies widely. Sometimes Google will have the best answer, sometimes Yahoo.
One gotcha to be aware of: if Google really thinks they don't know where your place is, they will return a 602 error indicating failure. Yahoo, on the other hand, if it can peel out a city/province/state/etc out of your bad address, will return the location of the center of that town. So you do have to pay attention to the results you get to see if they are really what you want. There are ancillary fields in some results that tell you about this: Yahoo calls this field "precision" and Google calls it "accuracy".
If you want to do this without relying on a service, then you download the TIGER Shapefiles from the US Census.
You look up the street you're interested in, which will have several segments. Each segment will have a start address and end address, and you interpolate along the segment to find where on the segment your house number lies.
This will provide you with a lon/lat pair.
Keep in mind, however, that online services employ a great deal of address checking and correction, which you'd have to duplicate as well to get good results.
Also note that as nice as free data is, it's not perfect - the latest streets aren't in there (they might be in the data Google uses), and the streets may be off their real location by some amount due to survey inaccuracies. But for 98% of geocoding needs it works perfectly, is free, and you control everything so you're reducing dependencies in your app.
Openstreetmaps has the aim of mapping everything in the world, though they aren't quite there it's worth keeping tabs on as they provide their data under a CC license
However, many (most?) other countries are only mapped by gov't or services for which you need to pay a fee. If you don't need to geocode very much data, then using Google, Yahoo, or some of the other free worldwide mapping services may be enough.
If you have to geocode a lot of data, then you will be best served by leasing map data from a major provider, such as teleatlas.
-Adam
You could also try the OpenStreetMap NameFinder, which contains open source, wiki-like street data for (potentially) the entire world. NameFinder will cease to exist at the end of august, but Nominatim is its replacement.
Google requires you to show a Google map with their data, with a max of 2.5k (was 25k) HTTP requests per day. Useful but you have to watch usage.
They do have
http://groups.google.com/group/Google-Maps-API/web/resources-non-google-geocoders
(Google has since removed this. If you see a duplicate or cache, I'll link to that.)
...in which I found GeoNames which has both a downloadable db, free web service and a commercial web service.
Google's terms of service will let you use their geocoding API for free if your website is in turn free for consumers to use. If not you will have to get a license for the Enterprise Maps.
For use with Drupal and PHP (and easily modified):
function get_lat_long($address) {
$res = drupal_http_request('http://maps.googleapis.com/maps/api/geocode/json?address=' . $address .'&sensor=false');
return json_decode($res->data)->results[0]->geometry->location;
}
You can have a look at the Google Maps API docs here to get a start on this:
http://code.google.com/apis/maps/documentation/services.html#Geocoding
It also seems to be something that you can do for international addresses using Live Maps also:
http://virtualearth.spaces.live.com/blog/cns!2BBC66E99FDCDB98!1588.entry
You can also do this with Microsoft's MapPoint Web Services.
Here's a blog post that explains how:
http://www.codestrider.com/BlogRead.aspx?b=b5e8e275-cd18-4c24-b321-0da26e01bec5
R Code to get the latitude and longitude of a street address
# CODE TO GET THE LATITUDE AND LONGITUDE OF A STREET ADDRESS WITH GOOGLE API
addr <- '6th Main Rd, New Thippasandra, Bengaluru, Karnataka' # set your address here
url = paste('http://maps.google.com/maps/api/geocode/xml?address=', addr,'&sensor=false',sep='') # construct the URL
doc = xmlTreeParse(url)
root = xmlRoot(doc)
lat = xmlValue(root[['result']][['geometry']][['location']][['lat']])
long = xmlValue(root[['result']][['geometry']][['location']][['lng']])
lat
[1] "12.9725020"
long
[1] "77.6510688"
If you want to do this in Python:
import json, urllib, urllib2
address = "Your address, New York, NY"
encodedAddress = urllib.quote_plus(address)
data = urllib2.urlopen("http://maps.googleapis.com/maps/api/geocode/json?address=" + encodedAddress + '&sensor=false').read()
location = json.loads(data)['results'][0]['geometry']['location']
lat = location['lat']
lng = location['lng']
print lat, lng
Note that Google does seem to throttle requests if it sees more than a certain amount, so you do want to use an API key in your HTTP request.
I had a batch of 100,000 records to be geocode and ran into Google API's limit (and since it was for an internal enterprise app, we had to upgrade to their premium service which is $10K plus)
So, I used this instead: http://geoservices.tamu.edu/Services/Geocode/BatchProcess/ -- they also have an API. (the total cost was around ~200$)
You can try this in JavaScript for city like kohat
var geocoder = new google.maps.Geocoder();
var address = "kohat";
geocoder.geocode( { 'address': address}, function(results, status) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
alert(latitude+" and "+longitude);
}
});
In python using geopy PyPI used to get the lattitude,langitude,zipcode etc..
Here is the working sample code..
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="your-app-id")
location = geolocator.geocode("Your required address ")
if location:
print('\n Nominatim ADDRESS :',location.address)
print('\n Nominatim LATLANG :',(location.latitude, location.longitude))
print('\n Nominatim FULL RESPONSE :',location.raw)
else:
print('Cannot Find')
In Nominatim - Some addresses can't working, so i just tried MapQuest.
It returns correctly.
Mapquest provides free-plan 15000 transactions/month. It is enough for me.
Sample code:
import geocoder
g = geocoder.mapquest("Your required address ",key='your-api-key')
for result in g:
# print(result.address, result.latlng)
print('\n mapquest ADDRESS :',result.address,result.city,result.state,result.country)
print('\n mapquest LATLANG :', result.latlng)
print('\n mapquest FULL RESPONSE :',result.raw)
Hope it helps.
I know this is old question but google changing way to get latitude and longitude on regular based.
HTML code
<form>
<input type="text" name="address" id="address" style="width:100%;">
<input type="button" onclick="return getLatLong()" value="Get Lat Long" />
</form>
<div id="latlong">
<p>Latitude: <input size="20" type="text" id="latbox" name="lat" ></p>
<p>Longitude: <input size="20" type="text" id="lngbox" name="lng" ></p>
</div>
JavaScript Code
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>
<script>
function getLatLong()
{
var address = document.getElementById("address").value;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
document.getElementById("latbox").value=latitude;
var longitude = results[0].geometry.location.lng();
document.getElementById("lngbox").value=longitude;
}
});
}
</script>