The Road to Delphi

Delphi – Free Pascal – Oxygene

Using the Bing search API from Delphi

8 Comments

The 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 results from the Bing Engine. In this article I will show how you can use this API from Delphi.

Getting Started

Before to start read the terms of use of the Bing API which states “…The API is intended to deliver relevant results (collectively, “Bing results”) for queries submitted to Microsoft’s Bing service and other related Microsoft services (collectively, “Bing services”) for rendering within a customer-facing or end-user-facing website (“Website”) or application..(So it’s ok use this API from a desktop application)

To use the Bing API you must get an Application ID from the Bing Developer Center and include this AppId in the API calls.

You can send a request to the Bing Search API and get the response in one of these protocols JSON (JavaScript Object Notation), XML (Extended Markup Language) or SOAP (Simple Object Access Protocol).

The protocol is identified in the used URI, check these samples URLs

Before to choose the appropriate response protocol you must evaluate the kind of application which are you developing, in this article I choose the XML protocol due that can be implemented im most of the delphi versions without use third party libraries (Note : the only limitation using the XML response is which the length of the requested URL is limited by the maximum URL length.)

Building the URL

When you uses the Bing XML interface, you must make a HTTP GET using a URL like this

http://api.bing.net/xml.aspx?AppId= YOUR_APPID &Version=2.2&Market=en-US&Query=testign&Sources=web+spell&Web.Count=1&xmltype=elementbased

  • Appid : is the Application ID
  • Version : Version of the API to use (recommended is 2.2)
  • Market : prefered language of the search results
  • Query : the sentence to search
  • Web.Count : the number of results to get
  • xmltype : this field control control the flavor of XML interface. If ElementBased enumeration is specified, each field will be rendered as a separated tag. If AttributeBased enumeration is specified, all simple type fields will be rendered as attributes instead of elements. The default value is ElementBased.
  • Sources : indicate the types of data to retrieve (see Working with SourceTypes) (you can use multiple values in this files separated by an +)

the values of this field can be

  • Image (Bing, Version 2.0)
  • News (Bing, Version 2.0)
  • Phonebook  (Bing, Version 2.0)
  • RelatedSearch(Bing, Version 2.0)
  • Spell(Bing, Version 2.0)
  • Translation (Bing, Version 2.2)
  • Video (Bing, Version 2.x)
  • Web (Bing, Version 2)

Depending of how you construct your URL the XML returned can vary (see Using XML (Bing, Version2) for a sample output XML).

The code

After of build the URL you must make a GET request to access the Bing API. you can use your favorite component like WinInet, Indy and so on. In my case I choose the IXMLHTTPRequest interface to make GET request because I can use the same object to parse the XML result.

Check the next snippets using the AttributeBased and elementbased values in the xmltype field and how the parse procedure changes depending of this value.


{$APPTYPE CONSOLE}

uses
  MSXML,
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

//Demo of Attribute Based XML request
procedure GetBingInfoXML(const SearchKey : string;NumberOfResults:integer=1);
const
 //this AppId if for demo only please be nice and use your own , it's easy get one from here http://msdn.microsoft.com/en-us/library/ff512386.aspx
 ApplicationID= '73C8F474CA4D1202AD60747126813B731199ECEA';
 URI='http://api.bing.net/xml.aspx?AppId=%s&Version=2.2&Market=en-US&Query=%s&Sources=web&web.count=%d&xmltype=AttributeBased';
 COMPLETED=4;
 OK       =200;
var
  XMLHTTPRequest  : IXMLHTTPRequest;
  XMLDOMDocument  : IXMLDOMDocument;
  XMLDOMNode      : IXMLDOMNode;
  XMLDOMNodeList  : IXMLDOMNodeList;
  LIndex          : Integer;
begin
    XMLHTTPRequest := CreateOleObject('MSXML2.XMLHTTP') As IXMLHTTPRequest;
  try
    XMLHTTPRequest.open('GET', Format(URI,[ApplicationID, SearchKey, NumberOfResults]), False, EmptyParam, EmptyParam);
    XMLHTTPRequest.send('');
    if (XMLHTTPRequest.readyState = COMPLETED) and (XMLHTTPRequest.status = OK) then
    begin
      XMLDOMDocument := XMLHTTPRequest.responseXML  As IXMLDOMDocument2;
      XMLDOMNode := XMLDOMDocument.selectSingleNode('//web:Web');
      Writeln(Format('Total found %s',[String(XMLDOMNode.attributes.getNamedItem('Total').Text)]));
      Writeln;
      XMLDOMNodeList := XMLDOMNode.selectNodes('//web:WebResult');
      for LIndex:=0 to  XMLDOMNodeList.length-1 do
      begin
        XMLDOMNode:=XMLDOMNodeList.item[LIndex];
         Writeln(Format('Title       %s',[String(XMLDOMNode.attributes.getNamedItem('Title').Text)]));
         Writeln(Format('Description %s',[String(XMLDOMNode.attributes.getNamedItem('Description').Text)]));
         Writeln(Format('Url         %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
         Writeln(Format('CacheUrl    %s',[String(XMLDOMNode.attributes.getNamedItem('CacheUrl').Text)]));
         Writeln(Format('DisplayUrl  %s',[String(XMLDOMNode.attributes.getNamedItem('DisplayUrl').Text)]));
         Writeln(Format('DateTime    %s',[String(XMLDOMNode.attributes.getNamedItem('DateTime').Text)]));
         Writeln;
      end;
    end;
  finally
    XMLHTTPRequest := nil;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      GetBingInfoXML('delphi programming blogs', 5);
    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.

{$APPTYPE CONSOLE}

uses
  MSXML,
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

//Demo of element based XML request
procedure GetBingInfoXML(const SearchKey : string;NumberOfResults:integer=1);
const
 //this AppId if for demo only please be nice and use your own , it's easy get one from here http://msdn.microsoft.com/en-us/library/ff512386.aspx
 ApplicationID= '73C8F474CA4D1202AD60747126813B731199ECEA';
 URI='http://api.bing.net/xml.aspx?AppId=%s&Version=2.2&Market=en-US&Query=%s&Sources=web&web.count=%d&xmltype=elementbased';
 COMPLETED=4;
 OK       =200;
var
  XMLHTTPRequest  : IXMLHTTPRequest;
  XMLDOMDocument  : IXMLDOMDocument;
  XMLDOMNode      : IXMLDOMNode;
  XMLDOMNodeList  : IXMLDOMNodeList;
  LIndex          : Integer;
begin
    XMLHTTPRequest := CreateOleObject('MSXML2.XMLHTTP') As IXMLHTTPRequest;
  try
    XMLHTTPRequest.open('GET', Format(URI,[ApplicationID, SearchKey, NumberOfResults]), False, EmptyParam, EmptyParam);
    XMLHTTPRequest.send('');
    if (XMLHTTPRequest.readyState = COMPLETED) and (XMLHTTPRequest.status = OK) then
    begin
      XMLDOMDocument := XMLHTTPRequest.responseXML  As IXMLDOMDocument2;
      XMLDOMNode := XMLDOMDocument.selectSingleNode('//web:Total');
      Writeln(Format('Total found %s',[String(XMLDOMNode.text)]));
      Writeln;
      XMLDOMNodeList := XMLDOMNode.selectNodes('//web:WebResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
          Writeln(Format('Title       %s',[String(XMLDOMNode.selectSingleNode('./web:Title').Text)]));
          Writeln(Format('Description %s',[String(XMLDOMNode.selectSingleNode('./web:Description').Text)]));
          Writeln(Format('Url         %s',[String(XMLDOMNode.selectSingleNode('./web:Url').Text)]));
          Writeln(Format('CacheUrl    %s',[String(XMLDOMNode.selectSingleNode('./web:CacheUrl').Text)]));
          Writeln(Format('DisplayUrl  %s',[String(XMLDOMNode.selectSingleNode('./web:DisplayUrl').Text)]));
          Writeln(Format('DateTime    %s',[String(XMLDOMNode.selectSingleNode('./web:DateTime').Text)]));
          Writeln;
        end;
    end;
  finally
    XMLHTTPRequest := nil;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      GetBingInfoXML('delphi programming blogs', 5);
    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.

And calling any of these methods in this way

  GetBingInfoXML('delphi programming blogs', 5);

Will produce this output

Total found 7190000

Title       DelphiFeeds.com - All Delphi blogs in one place - Delphi community ...
Description Andy's Blog - I get some reports about problems with IDE Fix Pack 4.7. Those ... About Delphi Programming - in TTreeView :: Say you want to display customer-order-item data ...
Url         http://www.delphifeeds.com/
CacheUrl    http://cc.bingj.com/cache.aspx?q=delphi+programming+blogs&d=46646399
49310488&mkt=en-US&w=c537195d,718a1a7b
DisplayUrl  www.delphifeeds.com
DateTime    2012-03-30T13:36:00Z

Title       Delphi Programming Blog
Description Recently TMS Software released a FTP Uploader which I tried and liked because of its simplicity, but I was not satisfied with it because it did not reset itself to ...
Url         http://williamwmiller.wordpress.com/
CacheUrl    http://cc.bingj.com/cache.aspx?q=delphi+programming+blogs&d=4754451987498697&mkt=en-US&w=368ed92b,7b91d282
DisplayUrl  williamwmiller.wordpress.com
DateTime    2011-12-29T03:45:00Z

Title       RTTI « The Road to Delphi - a Blog about programming
Description Here 's a sample code of how you can dump the declaration of a TRttiType using the Rtti. Supports classes, records and interfaces. Delphi //Author ...
Url         https://theroadtodelphi.wordpress.com/category/delphi/rtti/
CacheUrl    http://cc.bingj.com/cache.aspx?q=delphi+programming+blogs&d=4925950032087641&mkt=en-US&w=c2546964,98458a
DisplayUrl  theroadtodelphi.wordpress.com/category/delphi/rtti
DateTime    2012-02-22T11:03:00Z

Title       2011 September « The Road to Delphi - a Blog about programming
Description Maybe you've seen articles about how use the FireMonkey Styles, and how you can set almost every aspect of a visual control, today I will go a step...
Url         https://theroadtodelphi.wordpress.com/2011/09/
CacheUrl    http://cc.bingj.com/cache.aspx?q=delphi+programming+blogs&d=5062478449739337&mkt=en-US&w=d5622f5e,eeaafc08
DisplayUrl  theroadtodelphi.wordpress.com/2011/09
DateTime    2012-03-05T17:17:00Z

Title       Delphi Programming Blog
Description Here's how to place a check box into a DBGrid. Create visually moreattractive user interfaces for editing boolean fields inside a DBGrid. ...
Url         http://delphi4all.blogfa.com/
CacheUrl    http://cc.bingj.com/cache.aspx?q=delphi+programming+blogs&d=4525654810627103&mkt=en-US&w=63fcb281,3d45a160
DisplayUrl  delphi4all.blogfa.com
DateTime    2012-03-25T01:10:00Z

As you probably note , the above source code only parses the result when the response includes a web search result, so now we are to expand this code to support and parse any result returned by the Bing API (Web search, Images, Videos, etc.)

Check the next full sample

{$APPTYPE CONSOLE}

{$R *.res}

uses
  MSXML,
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

type
  TBingApiSearchSource=(Image, News, RelatedSearch, Spell, Video,  Web);
  TBingApiSearchSources = Set of TBingApiSearchSource;

const
  BingApiSearchSourcesStr : Array [TBingApiSearchSource] of string = ('Image','News','RelatedSearch','spell','Video','Web');


procedure GetBingInfoExtXML(const SearchKey : string;const NumberOfResults:integer=1;Source : TBingApiSearchSources=[Web]);
const
 //this AppId if for demo only please be nice and use your own , it's easy get one from here http://msdn.microsoft.com/en-us/library/ff512386.aspx
 ApplicationID= '73C8F474CA4D1202AD60747126813B731199ECEA';
 URI='http://api.bing.net/xml.aspx?AppId=%s&Version=2.2&Market=en-US&Query=%s&Sources=%s&web.count=%d&xmltype=AttributeBased';
 COMPLETED=4;
 OK       =200;
var
  XMLHTTPRequest  : IXMLHTTPRequest;
  XMLDOMDocument  : IXMLDOMDocument;
  XMLDOMNode      : IXMLDOMNode;
  XMLDOMNodeList  : IXMLDOMNodeList;
  LIndex          : Integer;
  LSource         : TBingApiSearchSource;
  Sources         : string;
begin
    XMLHTTPRequest := CreateOleObject('MSXML2.XMLHTTP') As IXMLHTTPRequest;
  try
    Sources:='';
    for LSource in Source do
     Sources:=Sources+BingApiSearchSourcesStr[LSource]+'+';
    Delete(Sources,Length(Sources),1);

    XMLHTTPRequest.open('GET', Format(URI,[ApplicationID, SearchKey, Sources, NumberOfResults]), False, EmptyParam, EmptyParam);
    XMLHTTPRequest.send('');
    if (XMLHTTPRequest.readyState = COMPLETED) and (XMLHTTPRequest.status = OK) then
    begin
      XMLDOMDocument := XMLHTTPRequest.responseXML  As IXMLDOMDocument2;

      if Web in Source then
      begin
        XMLDOMNode := XMLDOMDocument.selectSingleNode('//web:Web');
        Writeln(Format('WebSearch results total found %s',[String(XMLDOMNode.attributes.getNamedItem('Total').Text)]));
        Writeln;
        XMLDOMNodeList := XMLDOMNode.selectNodes('//web:WebResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
           Writeln(Format('Title       %s',[String(XMLDOMNode.attributes.getNamedItem('Title').Text)]));
           Writeln(Format('Description %s',[String(XMLDOMNode.attributes.getNamedItem('Description').Text)]));
           Writeln(Format('Url         %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
           Writeln(Format('CacheUrl    %s',[String(XMLDOMNode.attributes.getNamedItem('CacheUrl').Text)]));
           Writeln(Format('DisplayUrl  %s',[String(XMLDOMNode.attributes.getNamedItem('DisplayUrl').Text)]));
           Writeln(Format('DateTime    %s',[String(XMLDOMNode.attributes.getNamedItem('DateTime').Text)]));
           Writeln;
        end;
      end;

      if Image in Source then
      begin
        XMLDOMNode := XMLDOMDocument.selectSingleNode('//mms:Image');
        Writeln(Format('Images results total found %s',[String(XMLDOMNode.attributes.getNamedItem('Total').Text)]));
        Writeln;
        XMLDOMNodeList := XMLDOMNode.selectNodes('//mms:ImageResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
           Writeln(Format('Title       %s',[String(XMLDOMNode.attributes.getNamedItem('Title').Text)]));
           Writeln(Format('MediaUrl    %s',[String(XMLDOMNode.attributes.getNamedItem('MediaUrl').Text)]));
           Writeln(Format('Url         %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
           Writeln(Format('DisplayUrl  %s',[String(XMLDOMNode.attributes.getNamedItem('DisplayUrl').Text)]));
           Writeln(Format('Width       %s',[String(XMLDOMNode.attributes.getNamedItem('Width').Text)]));
           Writeln(Format('Height      %s',[String(XMLDOMNode.attributes.getNamedItem('Height').Text)]));
           Writeln(Format('FileSize    %s',[String(XMLDOMNode.attributes.getNamedItem('FileSize').Text)]));
           Writeln(Format('ContentType %s',[String(XMLDOMNode.attributes.getNamedItem('ContentType').Text)]));
            XMLDOMNode:=XMLDOMNode.selectSingleNode('//mms:Thumbnail');
            if XMLDOMNode<>nil then
            begin
              Writeln(' Thumbnail Info');
              Writeln(Format(' Url         %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
              Writeln(Format(' ContentType %s',[String(XMLDOMNode.attributes.getNamedItem('ContentType').Text)]));
              Writeln(Format(' Width       %s',[String(XMLDOMNode.attributes.getNamedItem('Width').Text)]));
              Writeln(Format(' Height      %s',[String(XMLDOMNode.attributes.getNamedItem('Height').Text)]));
              Writeln(Format(' FileSize    %s',[String(XMLDOMNode.attributes.getNamedItem('FileSize').Text)]));
            end;
           Writeln;
        end;
      end;

      if Video in Source then
      begin
        XMLDOMNode := XMLDOMDocument.selectSingleNode('//mms:Video');
        Writeln(Format('Video results total found %s',[String(XMLDOMNode.attributes.getNamedItem('Total').Text)]));
        Writeln;
        XMLDOMNodeList := XMLDOMNode.selectNodes('//mms:VideoResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
           Writeln(Format('Title       %s',[String(XMLDOMNode.attributes.getNamedItem('Title').Text)]));
           Writeln(Format('PlayUrl     %s',[String(XMLDOMNode.attributes.getNamedItem('PlayUrl').Text)]));
           Writeln(Format('SourceTitle %s',[String(XMLDOMNode.attributes.getNamedItem('SourceTitle').Text)]));
           Writeln(Format('RunTime     %s',[String(XMLDOMNode.attributes.getNamedItem('RunTime').Text)]));
           Writeln(Format('Click Through Page Url %s',[String(XMLDOMNode.attributes.getNamedItem('ClickThroughPageUrl').Text)]));
            XMLDOMNode:=XMLDOMNode.selectSingleNode('//mms:StaticThumbnail');
            if XMLDOMNode<>nil then
            begin
              Writeln(' Static Thumbnail Info');
              Writeln(Format(' Url         %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
              Writeln(Format(' ContentType %s',[String(XMLDOMNode.attributes.getNamedItem('ContentType').Text)]));
              Writeln(Format(' Width       %s',[String(XMLDOMNode.attributes.getNamedItem('Width').Text)]));
              Writeln(Format(' Height      %s',[String(XMLDOMNode.attributes.getNamedItem('Height').Text)]));
              Writeln(Format(' FileSize    %s',[String(XMLDOMNode.attributes.getNamedItem('FileSize').Text)]));
            end;
           Writeln;
        end;
      end;


      if RelatedSearch in Source then
      begin
        Writeln('Related Searchs');
        Writeln;
        XMLDOMNodeList := XMLDOMDocument.selectNodes('//rs:RelatedSearchResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
          Writeln(Format('Title       %s',[String(XMLDOMNode.attributes.getNamedItem('Title').Text)]));
          Writeln(Format('Url         %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
        end;
      end;


      if News in Source then
      begin
        XMLDOMNode := XMLDOMDocument.selectSingleNode('//news:News');
        Writeln(Format('News results total found %s',[String(XMLDOMNode.attributes.getNamedItem('Total').Text)]));
        Writeln;
        XMLDOMNodeList := XMLDOMNode.selectNodes('//news:NewsResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
           Writeln(Format('Title        %s',[String(XMLDOMNode.attributes.getNamedItem('Title').Text)]));
           Writeln(Format('Url          %s',[String(XMLDOMNode.attributes.getNamedItem('Url').Text)]));
           Writeln(Format('Source       %s',[String(XMLDOMNode.attributes.getNamedItem('Source').Text)]));
           Writeln(Format('Snippet      %s',[String(XMLDOMNode.attributes.getNamedItem('Snippet').Text)]));
           Writeln(Format('Date         %s',[String(XMLDOMNode.attributes.getNamedItem('Date').Text)]));
           Writeln(Format('BreakingNews %s',[String(XMLDOMNode.attributes.getNamedItem('BreakingNews').Text)]));
           Writeln;
        end;
      end;

      if Spell in Source then
      begin
        XMLDOMNode := XMLDOMDocument.selectSingleNode('//spl:Spell');
        Writeln(Format('Spell results total found %s',[String(XMLDOMNode.attributes.getNamedItem('Total').Text)]));
        Writeln;
        XMLDOMNodeList := XMLDOMNode.selectNodes('//spl:SpellResult');
        for LIndex:=0 to  XMLDOMNodeList.length-1 do
        begin
          XMLDOMNode:=XMLDOMNodeList.item[LIndex];
           Writeln(Format('Value        %s',[String(XMLDOMNode.attributes.getNamedItem('Value').Text)]));
           Writeln;
        end;
      end;

    end;
  finally
    XMLHTTPRequest := nil;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      GetBingInfoExtXML('Delphi programming', 1, [Web, Video, Image]);
    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.

Author: Rodrigo

Just another Delphi guy.

8 thoughts on “Using the Bing search API from Delphi

  1. Hi.Thank you for sharing this example. When I try to use your example inside a form it always return an exception EAccessViolation if you use a high count value (like 100). Can you help avoiding it?

    • Send me a sample project with the issue.

      • I’m just testing a way to interface Bing (and Google) search. You can find the sample in: http://dl.dropbox.com/u/2208225/Spider.zip

        If you try with a count of 100 it always crashes (at least here). You can PM me at miguel dot enguica at me dot com . Thank you for your time!

        • The code access violation is caused because you are trying to get a value of a IXMLDOMNode which is nil, this is because sometimes the response of the bing service can contain an status error instead of seacrh result.

          Check this code which add the nil validation for the IXMLDOMNode and also handle the status error returnes by the bing service.

          procedure TForm2.GetBingInfoXML(const SearchKey : string;NumberOfResults:integer=1);
          const
           //this AppId if for demo only please be nice and use your own , it's easy get one from here http://msdn.microsoft.com/en-us/library/ff512386.aspx
           ApplicationID= hidden hidden 
           URI='http://api.bing.net/xml.aspx?AppId=%s&Version=2.2&Market=en-US&Query=%s&Sources=web&web.count=%d&xmltype=elementbased';
           COMPLETED=4;
           OK       =200;
          var
            XMLHTTPRequest  : IXMLHTTPRequest;
            XMLDOMDocument  : IXMLDOMDocument;
            XMLDOMNode      : IXMLDOMNode;
            CNode           : IXMLDOMNode;
            XMLDOMNodeList  : IXMLDOMNodeList;
            LIndex          : Integer;
          begin
              XMLHTTPRequest := CreateOleObject('MSXML2.XMLHTTP') As IXMLHTTPRequest;
            try
              XMLHTTPRequest.open('GET', Format(URI,[ApplicationID, SearchKey, NumberOfResults]), False, EmptyParam, EmptyParam);
              XMLHTTPRequest.send('');
              if (XMLHTTPRequest.readyState = COMPLETED) and (XMLHTTPRequest.status = OK) then
              begin
                XMLDOMDocument := XMLHTTPRequest.responseXML  As IXMLDOMDocument2;
                XMLDOMNode := XMLDOMDocument.selectSingleNode('//web:Total');
                if XMLDOMNode<>nil then
                begin
                  Memo1.Lines.Add(Format('Total found %s',[String(XMLDOMNode.text)]));
                  Memo1.Lines.Add('---');
                  XMLDOMNodeList := XMLDOMNode.selectNodes('//web:WebResult');
          
                  for LIndex:=0 to  XMLDOMNodeList.length-1 do
                  begin
                    XMLDOMNode:=XMLDOMNodeList.item[LIndex];
          
                    CNode:=XMLDOMNode.selectSingleNode('./web:Title');
                    if CNode<>nil  then
                    Memo1.Lines.Add(Format('Title       %s',[String(CNode.Text)]));
          
                    CNode:=XMLDOMNode.selectSingleNode('./web:Description');
                    if CNode<>nil  then
                    Memo1.Lines.Add(Format('Description %s',[String(CNode.Text)]));
          
                    CNode:=XMLDOMNode.selectSingleNode('./web:Url');
                    if CNode<>nil  then
                    Memo1.Lines.Add(Format('Url         %s',[String(CNode.Text)]));
          
          
                    CNode:=XMLDOMNode.selectSingleNode('./web:CacheUrl');
                    if CNode<>nil  then
                    Memo1.Lines.Add(Format('CacheUrl    %s',[String(CNode.Text)]));
          
                    CNode:=XMLDOMNode.selectSingleNode('./web:DisplayUrl');
                    if CNode<>nil  then
                    Memo1.Lines.Add(Format('DisplayUrl  %s',[String(Cnode.Text)]));
          
                    CNode:=XMLDOMNode.selectSingleNode('./web:DateTime');
                    if CNode<>nil  then
                    Memo1.Lines.Add(Format('DateTime    %s',[String(CNode.Text)]));
                    Memo1.Lines.Add('---');
                  end;
                end
                else
                Memo1.Lines.Add(XMLHTTPRequest.responseText);
          
              end;
            finally
              XMLHTTPRequest := nil;
            end;
          end;
          
  2. Hi Rodrigo. Once again thank you for your time! The exception error is gone, but when I perform a search asking for more than 50 results (ex: param web.count=51) the reply from the Bing server is always:

    microsoft1002Parameter has invalid value.SearchRequest.Web.Count51http://msdn.microsoft.com/en-us/library/dd251042.aspx

    When you enter a web.count under 50 it all works. Is there any limitation from the Bing API to retrieve only the first 50 results?

  3. To retrieve more results you must play with the parameter web.offset as described in:

    http://msdn.microsoft.com/en-us/library/dd250920

    Once again, thank you!

  4. Pingback: Using the Bing search API (Windows Azure Marketplace version) from Delphi « The Road to Delphi – a Blog about programming

Leave a comment