線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3384
推到 Plurk!
推到 Facebook!

用 Delphi 呼叫 Google 的 Search Engine

 
Diviner
初階會員


發表:36
回覆:112
積分:34
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-05-15 03:52:38 IP:61.10.xxx.xxx 未訂閱
用 Delphi 呼叫 Google 的 Search Engine: Delphi 能讓開發者以 SOAP 技術進行遠端呼叫, 我希望透過例子讓各位朋友一同向這方向研究研究。最近 Google Search Engine 提供了一組 Web Services, 讓用戶透過 SOAP 呼叫其網上搜尋服務, 也就是說, 我們可以替自己開發的程式, 加一個網上搜尋功能進去, 其搜尋的強度, 就是 Google 搜尋的強度, 因為盡管表面上是我們的程式介面讓用戶輸入搜尋條件, 實則背後是 Google 替我們進行搜尋, 然後把搜尋結果傳回給我們的程式而已。Google 是一個我很喜歡用的 Search Engine, 所以我很喜歡這個範例, 希望你也同樣喜歡。 首先第一個步驟是到 Google 拿到這個呼叫服務的 Google Web APIs Developer's Kit, 網址是 http://www.google.com/apis/ , 這個 Kit 的大小只有 642k, 不算大, 下載回來吧。 第二步是登記一個帳號, 只有申請到這個帳號, Google 才讓你呼叫她的搜尋服務, 這也很合理的, 她要控制資源。免費的帳號, 每天只會讓你搜尋 1000 次, 應該也夠玩吧, 收費的帳號就沒細究了。申請帳號不複雜, 都像是申請其他網上資源一樣, 先給你確認信, 確認信中有個 HyperLink, 按下確認後 Google 會寄給你第二封信, 告知你帳號申請成功, 並在信中附上一個 License Key (這個 Key 看起來像這樣的字串: "o2/Xx4mvQCafLDZ y90hA2Qso9PxSHkN"), 這個 License Key 是稍後在 SOAP 進行遠端呼叫時, 放在呼叫函數中作為參數傳遞給 Google, 然後呼叫才會通過的。 在 Delphi 中作 SOAP 遠端呼叫, 我使用了 Early Binding, 也就是一種編譯時期已可很大程度上確定呼叫句法沒有出錯的方法, 例如呼叫函數名稱出錯, 參數的資料型別的出錯等, 都在 Compile 時被指正, 且執行速度也是比較快的方法。相對於 Late Binding 而言, Late Binding 雖然執行速度較慢, 及要小心 Run Time Error 之外, 寫法卻又比較簡潔, 是為各有利弊; 而且, 目前 Delphi 要使用 SOAP 進行 Late Binding 的 SOAP 呼叫, 是要借助 MS SOAP Kit 的, 這個我還未試過, 有經驗的朋友, 也請在這裡分享一下經驗。 言歸正傳, Delphi 進行 Early Binding 時需要一個 Interface, 讓 Delphi 編譯時作為依據, 通常這個 Interface 會獨立放在一個 Unit 中, 可是目前我們連怎樣呼叫 Google 的服務都不知道, 又如何替她寫一個 Interface 呢? 我們怎麼知道 Google 提供的呼叫函式叫甚麼名稱呢? 函式需要甚麼參數呢? 傳回怎麼樣的資料呢? 不用擔心, 這些資料, SOAP 是以一個 WSDL 文件來描述的, Google 會提供這個文件給你, 讓你及 Delphi 懂得呼叫其服務。 WSDL (Web Service Definition Language) 是個 XML 格式的文件, Delphi 有一個工具能把這個 XML 格式的文件轉換成 Pascal 格式, 好讓你進行前面所說的 Early Binding, 這個工具便做 Web Service Importer Wizard。我們如何從 Google 取得這個文件呢? 這個文件在其 Development's Kit 中, 叫做 "GoogleSearch.wsdl", 不過我還是建議你直接到 Google 去拿, 因為說不定 Google 有新版本的 WSDL 文件。根據 Google 提供的資料, 她把 WSDL 文件放在 http://api.google.com/GoogleSearch.wsdl。 材料算是齊了, 現在到 Delphi 6 出場了。開個新 Project, 畫面的設計先不說, 我們先用 Web Service Importer Wizard 把 Pascal 格式的 Interface 轉換出來。按 File/New/Other, 選 WebServices 頁中的 WSDL Importer, 在其 WSDL Source 框中的 Location of WSDL File or URL 中填上 http://api.google.com/GoogleSearch.wsdl, 按 Next, 再按 Finish, Importer 便會將 WSDL 文件轉換為 Pascal 格式 Unit, 並自動加進目前的 Project 中了, Unit 名稱應該叫做 GoogleSearch, 請在 Form 中 uses 這個 Unit, 以進行 Early binding。 接著在本程式的 Form 上放一個 THTTPRIO Component (Component 放在 WebServices Component Palette 中), 用以連接 Google Web Service。在 Object Inspector 中設定其 WSDLLocation 屬性為 http://api.google.com/GoogleSearch.wsdl (不用逐字鍵入, 一選便選得出來, 這就是 Early Binding 的優點), 接著設定 Service 屬性為 GoogleSearchService, Port 屬性設定為 GoogleSearchPort, 我把這個 THTTPRIO Component 命名為 wsGoogleSearch。 接下來, 我替程式設計了一個 Keyword 輸入欄, 搜尋鍵, 及兩個搜尋結果輸出盒, 就不慢慢描述了, 乾脆把 Form 的 source code 貼出來, 你應該不難看得明。
//*************************************************************
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Rio, SOAPHTTPClient, StdCtrls, ComCtrls, GoogleSearch;    type
  TForm1 = class(TForm)
    wsGoogleSearch: THTTPRIO;
    btnSearch: TButton;
    lvResultItem: TListView;
    lvResult: TListView;
    Edit1: TEdit;
    procedure btnSearchClick(Sender: TObject);
    procedure lvResultChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
  private
          SearchResult: GoogleSearchResult;
          procedure ShowResultItem(const item: ResultElement);
    { Private declarations }
  public
    { Public declarations }
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}    procedure TForm1.btnSearchClick(Sender: TObject);
        procedure ShowResult(const res: GoogleSearchResult);
    procedure AddLine(const c1, c2: String);
    var
      item: TListItem;
    begin
      item := lvResult.Items.Add;
      item.Caption := c1;
      item.SubItems.Add(c2);
    end;
  var
          i: Integer;
  begin
                lvResult.Clear;        for i := 0 to length(res.resultElements) - 1 do begin
            AddLine(res.resultElements[i].title, res.resultElements[i].URL);
    end;
  end;    var
        key, q, restrict, lr, ie, oe: String;
  start, maxResults: Integer;
  filter, safeSearch: Boolean;
begin
        key := 'o2/Xx4mvQCafLDZ y90hA2Qso9PxSHkN';
  q := Edit1.Text;
  start := 0;
  maxResults := 9;
  filter := true;
  restrict := 'countryTW';
  safeSearch := false;
  lr := 'lang_zh-TW'; // 英文:'lang_en', 繁體中文:'lang_zh-TW', 簡體中文:'lang_zh-CN'
  ie := 'utf8';        // 英文:'latin1', 繁體中文:'big5', 簡體中文:'gb', 多語言: 'utf8'
  oe := 'utf8'; // 英文:'latin1', 繁體中文:'big5', 簡體中文:'gb', 多語言: 'utf8'      btnSearch.Enabled := False;
        SearchResult := (wsGoogleSearch as GoogleSearchPort).doGoogleSearch
                  (key, q, start, maxResults,        filter, restrict, safeSearch, lr, ie, oe);
  btnSearch.Enabled := True;      ShowResult(SearchResult);
end;    procedure TForm1.ShowResultItem(const item: ResultElement);
  procedure AddLine(const c1, c2: String);
  var
    item: TListItem;
  begin
    item := lvResultItem.Items.Add;
    item.Caption := c1;
    item.SubItems.Add(c2);
  end;
begin
  lvResultItem.Clear;      AddLine('Summary', item.summary);
  AddLine('URL', item.URL);
  AddLine('Snippet', item.snippet);
  AddLine('Title', item.title);
  AddLine('Host Name', item.hostName);
  AddLine('Director Category(full viawable name)', item.directoryCategory.fullViewableName);
  AddLine('Director Category(special encoding)', item.directoryCategory.specialEncoding);
  AddLine('Directory Title', item.directoryTitle);
  AddLine('Class Name', item.ClassName);
end;    procedure TForm1.lvResultChange(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
        if lvResult.ItemIndex <> -1 then
          ShowResultItem(SearchResult.resultElements[lvResult.ItemIndex]);
end;    end.
//*************************************************************
得某網友(忘了名稱, 又被駭客刪掉了文章)指正, 用 UTF8 作多語系搜尋, 便能成功使用中文作關鍵字作搜尋, 謝謝。 (mailto:diviner@i-cable.com)。 上文如有錯誤, 或有甚麼建議, 也請通知一下, 謝謝。 作者: 陳柱民
發表人 - diviner 於 2002/05/29 01:28:34 發表人 - diviner 於 2002/05/29 23:40:39
------
--
小卜子
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-05-20 07:58:18 IP:61.219.xxx.xxx 未訂閱
感謝網友Diviner貢獻文章"用 Delphi 呼叫 Google 的 Search Engine"! ~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
andersonhsieh
版主


發表:33
回覆:531
積分:439
註冊:2002-06-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-07-15 21:49:48 IP:211.23.xxx.xxx 未訂閱
我照你的方式做當按下查詢時會產生如下圖的錯誤 @@~~飛翔在天際的精靈~~@@
------
@@~~飛翔在天際的精靈~~@@
design
一般會員


發表:0
回覆:1
積分:0
註冊:2002-06-20

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-07-23 17:34:02 IP:210.201.xxx.xxx 未訂閱
引言: 我照你的方式做當按下查詢時會產生如下圖的錯誤 @@~~飛翔在天際的精靈~~@@
當你要使用對方提供的Web Service的Interface時別忘了使用Delhpi提供的Web Service Importer Wizard將該Interface Import到你的Project裡頭,並uses 該Unit醬子就不會有你所說的那個訊息了!
vv
一般會員


發表:0
回覆:3
積分:0
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-07-25 21:14:49 IP:211.75.xxx.xxx 未訂閱
最近研究web service ,得此寶貴的實作樣本, 真的謝謝大大級原作陳先生.
chfamy
中階會員


發表:87
回覆:161
積分:54
註冊:2002-05-03

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-01-14 12:33:34 IP:61.219.xxx.xxx 未訂閱
實作一個程式D6確實可以搜尋資料,但如搜尋"中文"關鍵字結果與直接於Google.com.tw輸入"中文"關鍵字結果不同,"英文"關鍵字結果一樣,不知 原因為何?
alanfujitsu
一般會員


發表:5
回覆:9
積分:2
註冊:2004-02-03

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-02-04 17:02:40 IP:211.21.xxx.xxx 未訂閱
太神奇了呢.."^_^
系統時間:2024-04-27 22:07:17
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!