Blog
All Blog Posts | Next Post | Previous PostUsing the Microsoft Bing API from Delphi
Tuesday, July 28, 2009
With the Bing API, Microsoft provides a set of easy to use services that can be useful for your Delphi web applications as well as Win32 applications. A starting point to discover the capabilities of the Bing API is http://www.bing.com/developers. The first thing you need to do to get started with the Bing API is getting a Bing AppID. The URL to apply for a Bing AppID is http://www.bing.com/developers/createapp.aspx. Basically, using the Bing API is free on the condition you respect the Microsoft terms of usage which are fortunately quite flexible.When you have the AppID, you're ready to start. The easiest way to use the Bing API is by using the HTTP GET request that returns an XML file with results. The Bing API provides access to several search types. The search type is defined as a SourceType. In the v2.0 API, following source types are available:
- Ad SourceType: get content related ads
- Image SourceType: search an image
- InstantAnswer SourceType: get direct answer to questions like "what is the capital city of Germany"
- MobileWeb SourceType:
- News SourceType: get information from news headlines
- Phonebook SourceType: get address & phone number information
- RelatedSearch SourceType: get a related search question
- Spell SourceType: perfom spell checking
- Translation SourceType: perform a translation
- Video SourceType: search a video
- Web SourceType: perform a regular web search
http://api.bing.net/xml.aspx?Appid=YourAppID &Query=YourQueryString &Sources=YourSourceType(s) + more options
This HTTP GET request returns an XML file containing the results. Delphi 2009 provides all required components to start using the API. You can use the Indy TidHTTP component to do the HTTP GET request and the TXMLDocument component to parse the result XML file. To make it ourselves even easier, we're going to use the TWebCopy component here to get the result XML file and TXMLDocument to parse the result.
Example 1: Searching the web
Searching the web is performed with the 'web' SourceType. A typical request looks like:
http://api.bing.net/xml.aspx?Appid=YourAppID &Query=Delphi&Sources=web
Optional, we can set the requested number of results and the offset of the result, ie:
http://api.bing.net/xml.aspx?Appid=YourAppID &Query=Delphi&Sources=web&web.count=20&web.offset=40
To quickly get the result XML file, we use TWebCopy in following way:
with webcopy.Items.Add do begin // AppID is a string constant containing our AppID, searchstr is our search query. url := 'http://api.search.live.net/xml.aspx?Appid=' + AppID + '&query='+HTTPEncode(searchstr)+'&sources=web&web.count='+inttostr(count)+'&web.offset='+inttostr(offset); TargetFilename := 'response.xml'; Protocol := wpHttp; end; webcopy.ShowDialog := false; webcopy.Execute;
xmldoc := TXMLDocument.Create(application); xmldoc.LoadFromFile('response.xml'); inode := xmldoc.ChildNodes.FindNode('SearchResponse'); if Assigned(inode) then begin uri := 'http://schemas.microsoft.com/LiveSearch/2008/04/XML/web'; mnode := inode.ChildNodes.FindNode('Web',uri); if Assigned(mnode) then begin rnode := mnode.ChildNodes.FindNode('Results',uri); if Assigned(rnode) then begin Result := TStringList.Create; for j := 0 to rnode.ChildNodes.Count - 1 do begin irnode := rnode.ChildNodes.Nodes[j]; dnode := irnode.ChildNodes.FindNode('Description',uri); if Assigned(dnode) then Result.Add(dnode.NodeValue); end; end; end; end; xmldoc.Free;
Example 2: Translating a text from English to German
The Bing API also offers a service to translate text from a source language to a target language. The HTTP query is very similar to the web search. We just need to specify the SourceType as Translation and specify the translation source language option and translation target language option. We encapsulated all this in one easy to use function:
function HTTPEncode(const AStr: string): string; const NoConversion = ['A'..'Z', 'a'..'z', '*', '@', '.', '_', '-']; var i: integer; begin Result := ''; for i := 1 to Length(AStr) do begin if CharInSet(AStr[i],NoConversion) then Result := Result + AStr[i] else Result := Result + Format('%%%.2x',[ord(AStr[i])]); end; end; function GetTranslation(text, fromLang, toLang: string): string; var xmldoc: TXMLDocument; inode,mnode,rnode,irnode: IXMLNode; j: integer; uri: string; webcopy: TWebCopy; begin Result := ''; webcopy := TWebCopy.Create(application); try webcopy.Items.Clear; with webcopy.Items.Add do begin url := 'http://api.search.live.net/xml.aspx?Appid=' + AppID + '&query='+HTTPEncode(text)+ '&sources=translation'+ '&Translation.SourceLanguage=' + fromLang + '&Translation.TargetLanguage=' + toLang; TargetFilename := 'response.xml'; Protocol := wpHttp; end; webcopy.ShowDialog := false; webcopy.Execute; finally webcopy.Free; end; xmldoc := TXMLDocument.Create(application); try xmldoc.LoadFromFile('response.xml'); inode := xmldoc.ChildNodes.FindNode('SearchResponse'); if Assigned(inode) then begin uri := 'http://schemas.microsoft.com/LiveSearch/2008/04/XML/translation'; mnode := inode.ChildNodes.FindNode('Translation',uri); if Assigned(mnode) then begin rnode := mnode.ChildNodes.FindNode('Results',uri); if Assigned(rnode) then begin irnode := rnode.ChildNodes.FindNode('TranslationResult',uri); if Assigned(irnode) then Result := irnode.ChildNodes.FindNode('TranslatedTerm',uri).NodeValue; end; end; end; finally xmldoc.Free; end; end; begin // sample call: ShowMessage(GetTranslation('Hello world','En','De')); end;
Example 3: Perform a spelling correction
The Bing API can offer us English spell checking as well. Again, the interface is very similar, ie. a simple HTTP GET request with the SourceType Spell. We also encapsulated this API in one easy to use Delphi function:
function DoSpellCheck(text: string): string; var xmldoc: TXMLDocument; inode,mnode,rnode,irnode: IXMLNode; j: integer; uri: string; webcopy: TWebCopy; begin Result := ''; webcopy := TWebCopy.Create(application); try with webcopy.Items.Add do begin url := 'http://api.bing.net/xml.aspx?Appid=' + AppID + '&query='+HTTPEncode(text)+ '&Sources=Spell&Version=2.0&Market=en-us&Options=EnableHighlighting'; TargetFilename := 'response.xml'; Protocol := wpHttp; end; webcopy.ShowDialog := false; webcopy.Execute; finally webcopy.Free; end; xmldoc := TXMLDocument.Create(application); try xmldoc.LoadFromFile('response.xml'); inode := xmldoc.ChildNodes.FindNode('SearchResponse'); if Assigned(inode) then begin uri := 'http://schemas.microsoft.com/LiveSearch/2008/04/XML/spell'; mnode := inode.ChildNodes.FindNode('Spell',uri); if Assigned(mnode) then begin rnode := mnode.ChildNodes.FindNode('Results',uri); if Assigned(rnode) then begin irnode := rnode.ChildNodes.FindNode('SpellResult',uri); if Assigned(irnode) then Result := irnode.ChildNodes.FindNode('Value',uri).NodeValue; end; end; end; finally xmldoc.Free; end; end; begin // sample call with a forced spelling error ShowMessage( DoSpellCheck('Mispeling words is a common ocurrence') ); end;
While there are a couple of more interesting SourceType's such as News, InstantAnswer, Video, the concept is always identical. In this last example, we use the Bing API to retrieve the first image from the web that matches our search string and display it in the application. We make it ourselves easy here by using the TMS TWebImage that does all the work of downloading and displaying the result image. The resulting code is:
function GetImageLink(searchstr: string): string; var xmldoc: TXMLDocument; inode,mnode,rnode,irnode: IXMLNode; j: integer; uri: string; webcopy: TWebCopy; begin Result := ''; webcopy := TWebCopy.Create(application); try with webcopy.Items.Add do begin url := 'http://api.bing.net/xml.aspx?Appid=' + AppID + '&query='+HTTPEncode(searchstr)+'&sources=image&image.count=1'; TargetFilename := 'response.xml'; Protocol := wpHttp; end; webcopy.ShowDialog := false; webcopy.Execute; finally webcopy.Free; end; xmldoc := TXMLDocument.Create(application); try xmldoc.LoadFromFile('response.xml'); inode := xmldoc.ChildNodes.FindNode('SearchResponse'); if Assigned(inode) then begin uri := 'http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia'; mnode := inode.ChildNodes.FindNode('Image',uri); if Assigned(mnode) then begin rnode := mnode.ChildNodes.FindNode('Results',uri); if Assigned(rnode) then begin irnode := rnode.ChildNodes.Nodes[0]; if Assigned(irnode) then Result := irnode.ChildNodes.FindNode('MediaUrl',uri).NodeValue; end; end; end; finally xmldoc.Free; end; end; begin // sample retrieving an image hyperlink and show it on the form using a TWebImage component imageurl := GetImageLink('mercedes SL gullwing'); caption := imageurl; Screen.Cursor := crHourGlass; WebImage1.URL := imageurl; Screen.Cursor := crDefault; end;
Bruno Fierens
This blog post has received 2 comments.
2. Monday, June 22, 2015 at 5:46:14 PM
Does the translate example still work?
Alexandre
Alexandre
Garcia alexandre
All Blog Posts | Next Post | Previous Post
Peter Manning