Problem
I started working on an application for storing information about books I own and I figured out it would be great to have a page where all books would be represented by their covers. I reckon that in general having covers would greatly improve the look & feel of the website. My first idea was to simply allow users to load covers’ images from disk. As much as it did satisfy the general problem, the solution was far from neat. I could not help but see this as a big burden to the end users. So I figured out, let’s do it for them. Let’s find covers from the internet and let them choose which one they would like to use.
READ ME FIRST!
Sorry, but this particular part of the API has been recently disabled by Google. I will shortly post a revised version of this article to demonstrate an alternative solution.
11th of December 2015
Solution
Whenever I need to find a picture of basically anything I always use Google Images so my guess was that it should be able to help me this time as well. Of course imitating a browser search that a standard user would perform and then parsing the resulting html page was out of the question. Nevertheless, it’s Google, so I was sure there has to be some API for their most famous and most used product. Fortunately, there is one!
Final result
See the result below.

See the source code of demo implementation here.
Google Search API
Google provides an API to retrieve results of its searching engine in JSON/Atom format. In order to use it we need to send a request to https://ajax.googleapis.com/ajax/ services/search/images with proper parameters:
- rsz
- number of results we want to receive in response (up to 8),
- start
- lets you skip n-1 results that would be normally returned (allows you to load further pictures),
- q
- search query.
- callback
- name of a method that will process response set (if this parameter is present, the format of response will be JSON-P not JSON).
JSON-P implementation
I use jQuery method ajax and JSON-P format to execute cross-domain call. In general to use JSON-P in jQuery we need to specify proper dataType and code that will be responsible for processing query result.
1 2 3 4 5 6 7 8 9 |
$.ajax({ url: 'http://serviceurl', dataType: "jsonp", // we specify the usage of JSON-P success: function(response) { // here we put the code to process the result of query } }); |
For this particular problem code would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$.ajax({ url: 'https://ajax.googleapis.com/ajax/services/search/images', dataType: "jsonp", data: { v: "1.0", rsz: 8, start: 0, q: "cookie" }, success: function(response) { refreshImages(response); } }); |
Because there is dataType: “jsonp” parameter for ajax call I do not have to put a callback parameter to the request string send to Google Search. This will be handled by jQuery (see below request generated by framework). Callback parameter has been attached by jQuery with some random name of a method that should be called upon receiving a response. This method will execute the function provided in the success parameter of ajax call (in my case refreshImages(response)).
1 2 3 |
https://ajax.googleapis.com/ajax/services/search/images?callback=jQuery21306969929163024462_1430559312153&v=1.0&rsz=8&start=0&q=cookie |
Handling results
As we are dealing with JSON-P call a response format will be slightly different from pure JSON. It looks a bit as if we were trying to call a method within the code itself. As you can see the name of the method is the same as the name specified in the callback parameter when sending the request.
1 2 3 4 5 6 |
/* callback */ jQuery21306969929163024462_1430559312153({ "responseData": { [...] |
Fortunately we do not have care about that, what we receive to process is only the responseData object. Below you can see a single result returned in response from Google Search:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
"responseData": { "results": [{ "GsearchResultClass": "GimageSearch", "width": "1024", "height": "780", "imageId": "ANd9GcRw4qx_b-S_DGC0VgTXwxn831q__X8UoHpR0M3wf2gBgP6TFizOKprDOCM", "tbWidth": "150", "tbHeight": "114", "unescapedUrl": "http://fc06.deviantart.net/fs71/i/2013/287/a/4/coo__man____by_robthedoodler-d6qjhhi.jpg", "url": "http://fc06.deviantart.net/fs71/i/2013/287/a/4/coo__man____by_robthedoodler-d6qjhhi.jpg", "visibleUrl": "robthedoodler.deviantart.com", "title": "\u003cb\u003eCoo\u003c/b\u003e, man... by RobtheDoodler on DeviantArt", "titleNoFormatting": "Coo, man... by RobtheDoodler on DeviantArt", "originalContextUrl": "http://robthedoodler.deviantart.com/art/Coo-man-407376198", "content": "\u003cb\u003eCoo\u003c/b\u003e, man... by RobtheDoodler", "contentNoFormatting": "Coo, man... by RobtheDoodler", "tbUrl": "http://t0.gstatic.com/images?q\u003dtbn:ANd9GcRw4qx_b-S_DGC0VgTXwxn831q__X8UoHpR0M3wf2gBgP6TFizOKprDOCM" }, [...] |
In my case I wanted to use urls of images to display them on my website and let user decide which one he/she thinks is the best. The code responsible for updating images can be found below.
1 2 3 4 5 6 7 8 9 10 11 |
function refreshImages(response) { if (response.responseData === null) { alert('Sorry no more results!'); } else { for (i = 0; i <= 8; i++) { $("#"+i).attr("src", response.responseData.results[i].unescapedUrl); } } } |
Improvements
Loading more results
Even though there is a limit of 8 pictures we can get from the server in a single query, if we modify the start parameter we can ultimately retrieve more than 8 results (mind you using this method we can only retrieve up to 100 first results, after that a retrieved result set will be empty).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// lastQueriedName and currentSearchPosition are global variables function calculateStartPosition(bookName, shift) { // in case we query for a new book, we ignore shift param and return first results, // but otherwise ... if (lastQueriedName === bookName) { // we modify start position, the shift parameter is either negative or positive number, // respectively if we want to see previous or next results currentSearchPosition += shift; if (currentSearchPosition < 0) { // no reason to go below 0 currentSearchPosition = 0; } if (currentSearchPosition >= 100) { // no reason to go over 100 currentSearchPosition = 92; } } else { lastQueriedName = bookName; currentSearchPosition = 0; } return currentSearchPosition; } |
Change as you type
I have an input field where user provides a name of book, I want to refresh the covers as he/she types. To achieve that I use below jQuery code:
1 2 3 4 5 |
$("input").on("change keyup paste", function() { refreshCovers(); }); |
This does not work now. Google ajax search engine has been deprecated
Sadly yes, I believe it was working just fine few days ago. Well, thanks for letting me know, I need to update few of my projects then. Later I will probably update the tutorial as well.
Thanks for this. Please let us know if you get another API working!
Now you should have to use SIMPLE HTML DOM in order to retrive images from Google search engine
EXAMPLE
MANUAL
http://simplehtmldom.sourceforge.net/manual.htm
Hope this can help you
Take care
Sure Jimmy, thanks for the link. However, I have not created anything in PHP since 11 years 🙂
free google unofficial image search api. http://api.ababeen.com/
Demo: http://api.ababeen.com/api/demo.php