Skip to content
The Road to Delphi — Delphi, VCL, VCL Styles, UxTheme and WinAPI

Using the Bing search API (Windows Azure Marketplace version) from Delphi

,

Introduction

Some time ago I wrote a entry about how use the Bing search API from Delphi , now this API was migrated to the Windows Azure Marketplace so it’s time to upgrade the source code to access this API.

The Bing Search API allow you to get search results retrieving the results in XML or JSON format. This API offers multiple source types (or types of search results) with each query. For example you can request web, images, news, and video results for a single search query.

In order to use the Bing Search API you must obtain an account key in the Windows Azure Marketplace, Then this key must be used in a Basic Authentication scheme to authenticate the requests.

Building the URL

The next step is build a valid URL to make the GET request. This is the basic structure of a Bing Search URL.

https://api.datamarket.azure.com/Bing/Search/%5Bsourcetype%5D?Query=%5BSearchTerm%5D&$format=%5BResponse format]&$top=5&$skip=0

This sample URL which uses the Web source type.

https://api.datamarket.azure.com/Bing/Search/Web?Query=%27Delphi%27&$format=ATOM&$top=5&$skip=0

These are the URI Input parameters for the Web source type.

Name Sample values Type Required
Query Hello String         X
Adult Moderate String
Latitude 48.59 Double
Longitude -112.31 Double
Market en-US String
Options EnableHighlighting String
WebFileType XLS String
WebSearchOptions DisableQueryAlterations String

These are the fields returned in the response.

Name Type
ID Guid
Title String
Description String
DisplayUrl String
Url String

Indy Sample

Check this sample Delphi code which uses Indy to make the GET request.

[sourcecode language=”delphi” wraplines=”false”]
{$APPTYPE CONSOLE}

{$R *.res}

uses
MSXML,
ActiveX,
ComObj,
Variants,
IdURI,
IdHttp,
IdSSLOpenSSL,
SysUtils;

procedure GetBingInfoXML_Web(const SearchKey : string;Top, Skip : Integer);
const
ApplicationID= ‘put your key here’;
URI=’https://api.datamarket.azure.com/Bing/Search/Web?Query=%s&$format=ATOM&$top=%d&$skip=%d’;
var
XMLDOMDocument : IXMLDOMDocument;
XMLDOMNode : IXMLDOMNode;
cXMLDOMNode : IXMLDOMNode;
XMLDOMNodeList : IXMLDOMNodeList;
LIdHTTP : TIdHTTP;
LIOHandler : TIdSSLIOHandlerSocketOpenSSL;
LIndex : Integer;
Response: string;
begin
LIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
LIOHandler.SSLOptions.Method := sslvTLSv1;
LIOHandler.SSLOptions.Mode := sslmUnassigned;
LIOHandler.SSLOptions.VerifyMode := [];
LIOHandler.SSLOptions.VerifyDepth := 0;
LIOHandler.host := ”;

LIdHTTP:= TIdHTTP.Create(nil);
try
LIdHTTP.Request.ContentEncoding := ‘utf-8’;
LIdHTTP.Request.BasicAuthentication:= True;
LIdHTTP.Request.Username:=ApplicationID;
LIdHTTP.Request.Password:=ApplicationID;
LIdHTTP.IOHandler:= LIOHandler;
Response:=LIdHTTP.Get(Format(URI,[TIdURI.PathEncode(QuotedStr(SearchKey)), Top, Skip]));

XMLDOMDocument:=CoDOMDocument.Create;
try
XMLDOMDocument.loadXML(Response);
XMLDOMNode := XMLDOMDocument.selectSingleNode(‘/feed’);
XMLDOMNodeList := XMLDOMNode.selectNodes(‘//entry’);

if XMLDOMNodeList<>nil then
for LIndex:=0 to XMLDOMNodeList.length-1 do
begin
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:ID’,[LIndex]));
Writeln(Format(‘id %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:Title’,[LIndex]));
Writeln(Format(‘Title %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:Description’,[LIndex]));
Writeln(Format(‘Description %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:DisplayUrl’,[LIndex]));
Writeln(Format(‘DisplayUrl %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:Url’,[LIndex]));
Writeln(Format(‘Url %s’,[String(cXMLDOMNode.Text)]));

Writeln;
end;

finally
XMLDOMDocument:=nil;
end;
finally
LIdHTTP.Free;
end;
finally
LIOHandler.Free;
end;
end;

begin
try
CoInitialize(nil);
try
GetBingInfoXML_Web(‘delphi programming blogs’, 5, 0);
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format(‘EOleException %s %x’, [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ‘:’, E.Message);
end;
Writeln(‘Press Enter to exit’);
Readln;
end.
[/sourcecode]

IXMLHTTPRequest Sample

Check this sample Delphi code which uses the IXMLHTTPRequest interface to make the GET request.

[sourcecode language=”delphi” wraplines=”false”]
{$APPTYPE CONSOLE}

{$R *.res}

uses
MSXML,
ActiveX,
ComObj,
Variants,
IdURI,
SysUtils;

procedure GetBingInfoXML_Web(const SearchKey : string;Top, Skip : Integer);
const
ApplicationID= ‘put your key here’;
URI=’https://api.datamarket.azure.com/Bing/Search/Web?Query=%s&$format=ATOM&$top=%d&$skip=%d&#8217;;
COMPLETED=4;
OK =200;
var
XMLHTTPRequest : IXMLHTTPRequest;
XMLDOMDocument : IXMLDOMDocument;
XMLDOMNode : IXMLDOMNode;
cXMLDOMNode : IXMLDOMNode;
XMLDOMNodeList : IXMLDOMNodeList;
LIndex : Integer;
begin
XMLHTTPRequest := CreateOleObject(‘MSXML2.XMLHTTP’) As IXMLHTTPRequest;
XMLHTTPRequest.open(‘GET’,Format(URI,[TIdURI.PathEncode(QuotedStr(SearchKey)), Top, Skip]), False, ApplicationID, ApplicationID);
XMLHTTPRequest.send(”);
if (XMLHTTPRequest.readyState = COMPLETED) and (XMLHTTPRequest.status = OK) then
begin
XMLDOMDocument:=CoDOMDocument.Create;
try
XMLDOMDocument.loadXML(XMLHTTPRequest.responseText);
XMLDOMNode := XMLDOMDocument.selectSingleNode(‘/feed’);
XMLDOMNodeList := XMLDOMNode.selectNodes(‘//entry’);

if XMLDOMNodeList<>nil then
for LIndex:=0 to XMLDOMNodeList.length-1 do
begin
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:ID’,[LIndex]));
Writeln(Format(‘id %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:Title’,[LIndex]));
Writeln(Format(‘Title %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:Description’,[LIndex]));
Writeln(Format(‘Description %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:DisplayUrl’,[LIndex]));
Writeln(Format(‘DisplayUrl %s’,[String(cXMLDOMNode.Text)]));
cXMLDOMNode:=XMLDOMNode.selectSingleNode(Format(‘//entry[%d]/content/m:properties/d:Url’,[LIndex]));
Writeln(Format(‘Url %s’,[String(cXMLDOMNode.Text)]));
Writeln;
end;

finally
XMLDOMDocument:=nil;
end;
end;

end;

begin
try
CoInitialize(nil);
try
GetBingInfoXML_Web(‘delphi programming blogs’, 5, 0);
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format(‘EOleException %s %x’, [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ‘:’, E.Message);
end;
Writeln(‘Press Enter to exit’);
Readln;
end.
[/sourcecode]

Recommended Resources

2 responses

  1. […] Bing Search API 2.0 now is available in the Windows Azure Marketplace, check the updated article here. The Bing Search API provides a very flexible set of methods to submit queries and retrieve […]

  2. Ivan Rakyta Avatar
    Ivan Rakyta

    Your Indy Sample has unicode issue. I fixed it by getting response into stream created with Encoding.UTF8. I am not an expert for Indy but the reason might be empty response encoding.

Leave a Reply