Using Other Web Services

   

We will now examine and use a Web service made available by Google (not implemented in C++Builder 6 Enterprise, but in another development environment), with the obvious functionality to search Google.

Google Web APIs

Information about the official Google Web APIs (Beta 2 at the time of writing this book)as they call themcan be obtained from the Google Web site at http://www.google.com/apis/. I don't know why they call them simple APIs when, in fact, they are APIs made available as a Web service. Anyway, at the aforementioned URL, you can see that it takes only three steps to start to use the Google APIs:

  1. Download the developer's kit

  2. Create a Google Account

  3. Write your program using your license key

The first step is easy and consists of downloading a 658,031 Byte ZIP file with the complete Google API (currently at Beta 2, released April 11, 2002). Samples for Java as well as .NET, an API reference, andmost importantly for usthe GoogleSearch.wsdl file, which contains the WSDL definition for the GoogleSearch Web service. We'll use this file as a starting point in step 3, when we're building our Web service client with C++Builder 6.

Google Search Key

The second step involves creating a Google account. This sounds more dangerous than it really is. The use of the Google API is free (at least at the time of writing), but you need to pass a personal key that will allow you up to 1,000 search queries per day for noncommercial use only. To get this key, you need to register yourself with an existing email address and a password (although you can forget that password). An email message will be sent to the specified account in order to verify the email address. After you've received the email message and clicked the link inside, you will receive a second message with your special Google Search Key. In my case, that key is 1WpiIaxr+k+hbyYbRLZOJfg7X9NgI837. The key is included in the source code, so the project on the CD-ROM with this book will work right from the start, although it will only work 1,000 times each day (for all combined users of the executable). Therefore, you might want to register yourself and get your own personal Google Search key, which entitles you to 1,000 daily search queries for yourself.

Google Search

Armed with the GoogleSearch.wsdl file and the Google Search Key, we can start C++Builder 6 (Professional or Enterprise) and build our Web service client. Start a new C++Builder project and save the (empty) main form in GoogleForm.cpp and the project itself in Google42.bpr . The first thing we need to do now is to generate a C++ import unit for the WSDL definition found in the GoogleSearch.wsdl file, so activate File, New, Other, and select the WSDL Importer Wizard from the Object Repository. Instead of specifying a URL for the Google Search, you can use the local GoogleSearch.wsdl filethis is especially handy in case you do not have a live Internet connection available at all times because all information is in the local WSDL file.

Click on the Next button, which will show a preview of the generated import unit as well as a treeview with the GoogleSearch specific types, interfaces, and methods (as can be seen in Figure 19.12).

Figure 19.12. GoogleSearch types and interfaces.

graphics/19fig12.jpg

As we can see in the treeview, there are three structure types: DirectoryCategory , ResultElement , and GoogleSearchResult ; two array types: ResultElementArray and DirectoryCategoryArray ; and one interface called GoogleSearchPort with three member functions: doGetCachedPage , doSpellingSuggestion , and doGoogleSearch . After we click the Finish button, the C++ import unit is generated in file GoogleSearch.cpp with the type definitions in GoogleSearch.h .

To illustrate the things we can do with the result, here are the GoogleSearchResult , ResultElementArray , and ResultElement type summaries with only their __published property names (and not their private fields) taken from the generated GoodleSearch.h file:

 class ResultElement : public TRemotable {  __published:    __property AnsiString    summary;    __property AnsiString        URL;    __property AnsiString    snippet;    __property AnsiString      title;    __property AnsiString cachedSize;    __property bool       relatedInformationPresent;    __property AnsiString   hostName;    __property DirectoryCategory* directoryCategory;    __property AnsiString directoryTitle;  };  typedef DynamicArray<ResultElement*> ResultElementArray;    /* "urn:GoogleSearch" */  class GoogleSearchResult : public TRemotable {  __published:    __property bool       documentFiltering    __property AnsiString searchComments    __property int        estimatedTotalResultsCount    __property bool       estimateIsExact    __property ResultElementArray resultElements    __property AnsiString searchQuery    __property int        startIndex    __property int          endIndex    __property AnsiString searchTips    __property DirectoryCategoryArray directoryCategories    __property double     searchTime  }; 

The GoogleSearchPort interface with its three methods and their arguments is defined as follows :

 __interface INTERFACE_UUID("{0B396A82-A4DD-69A7-A771-6D80F8831A71}")    GoogleSearchPort : public IInvokable  {  public:    virtual TByteDynArray   doGetCachedPage(const AnsiString key,      const AnsiString url) = 0;    virtual AnsiString      doSpellingSuggestion(const AnsiString key,      const AnsiString phrase) = 0;    virtual GoogleSearchResult* doGoogleSearch(const AnsiString key,      const AnsiString q, const int start, const int maxResults,      const bool filter, const AnsiString restrict, const bool safeSearch,      const AnsiString lr, const AnsiString ie, const AnsiString oe) = 0;  };  typedef DelphiInterface<GoogleSearchPort> _di_GoogleSearchPort; 

And, of course, we also have the helpful GetGoogleSearchPort() function that will return the _di_GoogleSearchPort interface for instant use.

As you might have realized by now, the DirectoryCategory is not a type that we will use at this time, but the ResultItem and GoogleSearchResult are the two result classes that will be used in this section. The GoogleSearchResult contains the resultElements property that points to an array of ResultItems . Finally, the method goGoogleSearch() of the GoogleSearchPort interface is the most interesting, so let's examine that one in more detail.

doGoogleSearch

The definition of the doGoogleSearch() method of the GoogleSearchPort interface is as follows (this time with some meaningful comments for each argument):

 virtual GoogleSearchResult* doGoogleSearch(const AnsiString key,       // your own Google Search Key  const AnsiString q,;        // query string  const int start,            // start URLs  const int maxResults,       // maximum results  const bool filter,          // filter alike results?  const AnsiString restrict,  // restrictions  const bool safeSearch,      // adult filter?  const AnsiString lr,        // language?  const AnsiString ie,        // input encoding  const AnsiString oe) = 0;   // output encoding 

Ouch! A lot of arguments, that's for sure. Fortunately, the Google Search API ZIP-file that we downloaded earlier also contains a file APIs_Reference.html (of 100,417 bytes) containing more information about the search request formats and search results formats; including the meaning of the arguments to doGoogleSearch() .

The key argument is the Google Search Key that you have to obtain (we can use the key 1WpiIaxr+k+hbyYbRLZOJfg7X9NgI837). The q argument is the actual query (there's a subsection on the complete query syntax, which includes the site: option to specify that you want to search within a specific Web site). The start argument specifies where you want to start the results, and maxResults specifies how many results you want to receive (with a maximum of 10). Because you can only get a maximum of 10 results at a given time, start can be used to specify where to start. If start is 0, you get the first 10 results. To get the next 10 results, you must pass a value of 10 in start , and so on. This will quickly consume your 1,000 available daily queries, so be aware not to use this to obtain all 142,000 results for "Dr. Bob" on the Web. Personally, I think the first 10 results are just fine, so I use 0 for start and 10 for maxResults . The filter argument can be used to filter results that are very similar, something that I also often use at Google myself , so I pass true as value for filter . The restrict argument can be used to restrict the search query to a specific country or topic within Google. The safeSearch argument can be set to true to make sure you don't get any "adult" search results. Handy if you want to build your own custom search engine for your kids at home (although I haven't tested this fully to make sure it really works as advertised). The lr argument is a bit similar to the restrict argument, and can be used to select results in a specific language ( lr ), such as Dutch or English (there seem to be no distinction between English, American English, or any of the other English dialects). Finally, the ie and oe arguments specify the Input and Output Encoding, which can be set to latin1 for Dutch and English (see the reference document for more information).

In short, my call to doGoogleSearch() , for a given query string inside an TEdit called edtQuery , would look as follows:

 GetGoogleSearchPort()->doGoogleSearch("1WpiIaxr+k+hbyYbRLZOJfg7X9NgI837",  edtQuery->Text, 0, 10, True, "", True, "lang_en", "latin1", "latin1"); 

This would give us a result of type GoogleSearchResult , which is derived from TRemoteable . GoogleSearchResult is covered next.

GoogleSearchResult

The GoogleSearchResult has a number of useful properties such as estimatedTotal ResultsCount , searchTime , and resultElements . The last one is an array of which the elements are of type ResultElement , having a number of interesting subproperties such as title , URL , and cachedSize . We can use a TStringGrid to display the results. In fact, let's now build the GUI and actually write some code. The steps are as follows:

  1. Drop a TPanel component on the GoogleForm . Set its Align property to alTop , and clear the Caption property.

  2. Drop a TButton component on the right of the TPanel , set its Name property to btnSearch , its Caption property to Search , the Anchor->Right subproperty to true , and the Anchor->Left subproperty to false. These last two changes will ensure the button stays glued to the right of the panel, even if you resize the GoogleForm .

  3. Drop a TEdit component on the left side of the TPanel , and resize, so it almost reaches the TButton (see Figure 19.13). Set its Name to edtQuery , clear the Text property, and set the Anchor->Right subproperty to true .

    Figure 19.13. GoogleSearch Output.

    graphics/19fig13.jpg

  4. Drop a TStringGrid component on the GoogleForm , right under the TPanel , set its Align property to alClient , so the TStringGrid occupies the remainder of the GoogleForm . Set its ColCount property to 4, its RowCount property to 11 (that's 10 plus the header), set the DefaultRowHeight property to 21, and finally set the Options->goRowSelect subproperty to true.

  5. Now, resize the Form to make the StringGrid fit without scrolling. To initialize the columns of the StringGrid , write the follow code in the OnCreate event handler of the Form :

     void __fastcall TForm1::FormCreate(TObject *Sender)  {    StringGrid1->ColWidths[0] = 20;    StringGrid1->ColWidths[1] = (StringGrid1->ClientWidth - 55) / 2;    StringGrid1->ColWidths[2] = StringGrid1->ColWidths[1];    StringGrid1->ColWidths[3] = 32;    StringGrid1->Cells[0][0] = (AnsiString)" #";    StringGrid1->Cells[3][0] = (AnsiString)" KB";  } 

The OnClick event handler of the TButton component can be used to make the call to doGoogleSearch and show the results inside the TStringGrid component. This code is as follows:

 void __fastcall TForm1::btnSearchClick(TObject *Sender)  {    for (int row=1; row<=10; row++)      for (int col=0; col<=3; col++)        StringGrid1->Cells[col][row] = ""; // clear StringGrid    GoogleSearchResult* Results =      GetGoogleSearchPort()->doGoogleSearch("1WpiIaxr+k+hbyYbRLZOJfg7X9NgI837",      edtQuery->Text, 0, 10, True, "", True, "lang_en", "latin1", "latin1");    Caption = IntToStr(Results->estimatedTotalResultsCount) +      " results in " + FloatToStr(Results->searchTime) + " seconds.";    for (int i=Results->resultElements.Low;             i <= Results->resultElements.High; i++)    {      StringGrid1->Cells[0][i+1] = IntToStr(i+1);      StringGrid1->Cells[1][i+1] = Results->resultElements[i]->title;      StringGrid1->Cells[2][i+1] = Results->resultElements[i]->URL;      StringGrid1->Cells[3][i+1] = Results->resultElements[i]->cachedSize;    }  } 

The result is a Windows application that can be used to enter a number of search words and return the top 10 URLs. To jump directly to one of the resulting URLs, we only have to implement the OnDlbClick event handler of the TStringGrid , as follows:

 void __fastcall TForm1::StringGrid1DblClick(TObject *Sender)  {    TStringGrid* SG = dynamic_cast<TStringGrid*>(Sender);    ShellExecute(Handle,"open",SG->Cells[2][SG->Row].c_str(),NULL,0,SW_NORMAL);  } 

The best thing is that you can integrate this feature in your own (noncommercial) applications as well, of course. As long as an Internet connection is available to talk to Google's official Search Web service.

Apart from searching for keywords in a Windows GUI application (or added as a dialog to your own application), another good use of this functionality could be to add it to a Web site, transformed as Web server application. In that case, you can prefix the Query text with the site: keyword, including the name of the Web site you're looking at. For example, " site:www.drbob42.com " to look for the keyword in pages on my own Web site. As an example of the output, take a look at Figure 19.14 which shows a search for the BizSnap WebServices SOAP combination in the site:www.drbob42.com .

Figure 19.14. GoogleSearch Web sitespecific results.

graphics/19fig14.jpg


   
Top


C++ Builder Developers Guide
C++Builder 5 Developers Guide
ISBN: 0672319721
EAN: 2147483647
Year: 2002
Pages: 253

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net