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.
{$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.
IXMLHTTPRequest Sample
Check this sample Delphi code which uses the IXMLHTTPRequest interface to make the GET request.
{$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'; 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.
Pingback: Using the Bing search API from Delphi « The Road to Delphi – a Blog about programming
June 14, 2013 at 4:16 pm
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.