27

I am trying to programatically perform a search on Microsoft Bing search engine.

Here is my understanding:

  • There was a Bing Search API 2.0 , which will be replaced soon (1st Aug 2012)
  • The new API is known as Windows Azure Marketplace.
  • You use different URL for the two.

In the old API (Bing Search API 2.0), you specify a key (Application ID) in the URL, and such key will be used to authenticate the request. As long as you have the key as a parameter in the URL, you can obtain the results.

In the new API (Windows Azure Marketplace), you do NOT include the key (Account Key) in the URL. Instead, you put in a query URL, then the server will ask for your credentials. When using a browser, there will be a pop-up asking for a/c name and password. Instruction was to leave the account name blank and insert your key in the password field.

Okay, I have done all that and I can see a JSON-formatted results of my search on my browser page.

How do I do this programmatically in PHP? I tried searching for the documentation and sample code from Microsoft MSDN library, but I was either searching in the wrong place, or there are extremely limited resources in there.

Would anyone be able to tell me how do you do the "enter the key in the password field in the pop-up" part in PHP please?

Thanks alot in advance.

pnuts
  • 58,317
  • 11
  • 87
  • 139
Gapton
  • 2,044
  • 2
  • 20
  • 33

7 Answers7

37

Documentation for new services can get a bit interesting - especially in the rabbit-warren of MSDN. The most clear explanation I can find is on the Migration Guide from this Bing Search API page. Best of all the migration guide has a nice simple example in PHP towards the end.

EDIT: Alright, the migration guide is a starting point, but it isn't the best example. Here are two methods that work for me (no proxy, firewalls etc. interfering):

Using file_get_contents

Note: 'allow_url_fopen' needs to be enabled for this to work. You can use ini_set (or change php.ini etc.) if it isn't.

if (isset($_POST['submit'])) 
{

    // Replace this value with your account key
    $accountKey = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';            
    $ServiceRootURL =  'https://api.datamarket.azure.com/Bing/Search/';                    
    $WebSearchURL = $ServiceRootURL . 'Web?$format=json&Query=';

    $cred = sprintf('Authorization: Basic %s', 
      base64_encode($accountKey . ":" . $accountKey) );

    $context = stream_context_create(array(
        'http' => array(
            'header'  => $cred
        )
    ));

    $request = $WebSearchURL . urlencode( '\'' . $_POST["searchText"] . '\'');

    $response = file_get_contents($request, 0, $context);

    $jsonobj = json_decode($response);

    echo('<ul ID="resultList">');

    foreach($jsonobj->d->results as $value)
    {                        
        echo('<li class="resultlistitem"><a href="' 
                . $value->URL . '">'.$value->Title.'</a>');
    }

    echo("</ul>");
}

Using cURL

If cURL is installed, which is normal these days:

<?php
  $query = $_POST['searchText'];

  $accountKey = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
  $serviceRootURL =  'https://api.datamarket.azure.com/Bing/Search/';  
  $webSearchURL = $serviceRootURL . 'Web?$format=json&Query=';

  $request = $webSearchURL . "%27" . urlencode( "$query" ) . "%27";

  $process = curl_init($request);
  curl_setopt($process, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  curl_setopt($process, CURLOPT_USERPWD,  "$accountKey:$accountKey");
  curl_setopt($process, CURLOPT_TIMEOUT, 30);
  curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
  $response = curl_exec($process);
  $response = json_decode($response);

  echo "<ol>";
  foreach( $response->d->results as $result ) {
    $url = $result->Url;
    $title = $result->Title;

    echo "<li><a href='$url'>$title</a></li>";
  }
  echo "</ol>";
?>

[WTS] changed SearchWeb to Search.

Wonko the Sane
  • 754
  • 3
  • 14
  • 31
John C
  • 8,223
  • 2
  • 36
  • 47
  • Thanks I used their PHP sample but I keep getting failed to open stream: Connection refused error. I wonder if the header has been set correctly – Gapton Jun 01 '12 at 06:30
  • Did you also use their proxy line? – John C Jun 01 '12 at 13:57
  • 2
    Alternatively you could have a look at [curl](http://stackoverflow.com/questions/2140419/how-do-i-make-a-request-using-http-basic-authentication-with-php-curl) instead of file_get_contents. – John C Jun 01 '12 at 14:13
  • 1
    It is in essence correct, but as an example it could have been simplified. I've added two ways of doing it to my answer. – John C Jun 02 '12 at 08:56
  • 1
    it would appear the author made a new question and answered it himself: http://stackoverflow.com/q/10845672/628267 gg – John C Jun 05 '12 at 04:58
  • FYI: the login for the authenication can stay empty. one problem I had with java: bing assumes you are using %20 and not + and check the error stream as sometimes I missed those ugly apostrophes around the parameter input, but you'll get a message accordingly – Karussell Jul 03 '12 at 13:24
  • How would you do image search with Bing? Would `$WebSearchURL` change, and if so, what would it change to? – Mike Warren Dec 03 '14 at 01:28
  • 1
    At a glance you'd need to change `$serviceRootURL` to `https://api.datamarket.azure.com/Bing/Search/` and `$webSearchURL` to end with `Image?$format=json&Query=`. If you need more information I'd suggest posting a new question. – John C Dec 03 '14 at 12:23
  • 1
    /Bing/SearchWeb/ should be /Bing/Search/ -- that got it working for me – Kristopher Windsor Oct 20 '15 at 04:51
6

None of the above worked for me. Im running MAMP, this may be relevant. Try the below:


$accountKey = '=';


function sitesearch ($query, $site, $accountKey, $count=NULL){
  // code from http://go.microsoft.com/fwlink/?LinkID=248077

    $context = stream_context_create(array(
    'http' => array(
      'request_fulluri' => true,       
      'header'  => "Authorization: Basic " . base64_encode($accountKey . ":" . $accountKey)
    ) 
    )); 

    $ServiceRootURL =  'https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/News?Market=%27en-GB%27&';
    $WebSearchURL = $ServiceRootURL . '$format=json&Query=';  

    $request = $WebSearchURL . urlencode("'$query'"); // note the extra single quotes
    if ($count) $request .= "&\$top=$count"; // note the dollar sign before $top--it's not a variable!
    return json_decode(file_get_contents($request, 0, $context), true);
}


$q = "query";

if ($q){
  // get search results
  $articles = sitesearch ($q, $_SERVER['HTTP_HOST'], $accountKey , 100);

  foreach($articles['d']['results'] as $article) {
      echo " <p>".$article['Title'].'</p>';
      echo " <p>".$article['Description'].'</p>';
      echo " <p>".$article['Source'].'</p>';
      echo " <p>".strtotime($article['Date']).'</p>';
  }



}

FROM: http://bililite.com/blog/2012/06/05/new-bing-api/

Jim
  • 521
  • 8
  • 14
  • note that the source is set to `News`, here `$ServiceRootURL = 'https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/News?Market=%27en-GB%27&';` – Fallen Jul 22 '14 at 18:20
5

you can use bellow code to get bing search results

$acctKey = 'Your account key here';
$rootUri = 'https://api.datamarket.azure.com/Bing/Search';
$query = 'Kitchen';
$serviceOp ='Image';
$market ='en-us';
$query = urlencode("'$query'");
$market = urlencode("'$market'");
$requestUri = "$rootUri/$serviceOp?\$format=json&Query=$query&Market=$market";
$auth = base64_encode("$acctKey:$acctKey");
$data = array(  
            'http' => array(
                        'request_fulluri' => true,
                        'ignore_errors' => true,
                        'header' => "Authorization: Basic $auth"
                        )
            );
$context = stream_context_create($data);
$response = file_get_contents($requestUri, 0, $context);
$response=json_decode($response);
echo "<pre>";
print_r($response);
echo "</pre>";
kishore chowdary
  • 121
  • 2
  • 4
  • 11
  • Thank you. Finally someone bringing a shred of sanity to this API. My guess is that all of the previous responses worked at one point in time but Microsoft keeps changing stuff. – Nate Bunney Jun 09 '15 at 16:59
  • This one worked ;) thanks for sharing, the documentation at bing sux. – Sagive Jan 10 '16 at 23:34
4

http://www.guguncube.com/2771/python-using-the-bing-search-api

it contains python code to query the bing and this is according to latest new API (Windows Azure Marketplace)

# -*- coding: utf-8 -*-
import urllib
import urllib2
import json

def main():
    query = "sunshine"
    print bing_search(query, 'Web')
    print bing_search(query, 'Image')

def bing_search(query, search_type):
    #search_type: Web, Image, News, Video
    key= 'YOUR_API_KEY'
    query = urllib.quote(query)
    # create credential for authentication
    user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; FDM; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322)'
    credentials = (':%s' % key).encode('base64')[:-1]
    auth = 'Basic %s' % credentials
    url = 'https://api.datamarket.azure.com/Data.ashx/Bing/Search/'+search_type+'?Query=%27'+query+'%27&$top=5&$format=json'
    request = urllib2.Request(url)
    request.add_header('Authorization', auth)
    request.add_header('User-Agent', user_agent)
    request_opener = urllib2.build_opener()
    response = request_opener.open(request) 
    response_data = response.read()
    json_result = json.loads(response_data)
    result_list = json_result['d']['results']
    print result_list
    return result_list

if __name__ == "__main__":
    main()
mombul
  • 327
  • 1
  • 10
Ritesh
  • 497
  • 4
  • 15
  • You should copy/paste the code instead of just linked it, in case of it disapears or be moved in the future – AlexB Apr 09 '14 at 08:21
  • Thanks a lot for adding the python code. The Azure documentation link is giving 404 :) so it helped a lot. Do you have any idea as to how cant his work with the django_pipes project .. – pranshus Jun 20 '14 at 21:30
3

Don't forget to put this:

base64_encode("ignored:".$accountKey)

instead of:

base64_encode($accountKey . ":" . $accountKey)
Tisho
  • 8,320
  • 6
  • 44
  • 52
3

Here is a working example of the Search API just replace "XXXX" with your access key. Even I wasted quite a few hours trying to get it to work using cURL but it was failing because of "CURLOPT_SSL_VERIFYPEER" on local :( - so make sure your cURL opts are set properly.

$url = 'https://api.datamarket.azure.com/Bing/Search/Web?Query=%27xbox%27';
$process = curl_init($url);
curl_setopt($process, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($process, CURLOPT_USERPWD, base64_encode("username:XXXX"));
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($process);

# Deliver
return $response;

# Have a great day!
curl_close($process);
Kailash Yadav
  • 1,880
  • 2
  • 18
  • 37
  • 1
    This works!, the KEY here is that "username:key" is what should be base 64 encoded in the basic auth header and not just "key" :) – Rajiev Timal Aug 22 '14 at 18:28
1

Here is the example of how to call Bing/Azure API using Unirest library.

require_once '/path/to/unirest-php/lib/Unirest.php';

$accountKey = "xxx";
$searchResults = Unirest::get("https://api.datamarket.azure.com/Bing/Search/v1/Composite",
    array(),
    array(
        'Query' => '%27Microsoft%27',
        'Sources' => '%27web%2Bimage%2Bvideo%2Bnews%2Bspell%27',
        '$format' => 'json',
    ), $accountKey, $accountKey
);

// Results are here:
$objectArray = $searchResults->body->d->results;
$rawJson = $searchResults->raw_body;

You can omit Source parameter by defining it in the URL: https://api.datamarket.azure.com/Bing/Search/v1/Webor https://api.datamarket.azure.com/Bing/Search/v1/Image

Note: parameters in request URL are case-sensitive. For Bing they start with a capital letter.

Websirnik
  • 1,372
  • 3
  • 21
  • 35