相信 Delphi 中 TWebBrowser 組件大家都比較熟悉,用它自己進行製作瀏覽器非常簡單,論壇中和文檔中心中都談了很多,我這裡主要想談兩個兩個問題:
如何用 TWebBrowser 組件 POST 資料?
如何用 TWebBrowser 組件預覽 HTML 文檔片段?
因為工作需要,需用用到 TWebBrowser 組件的 POST 功能,查了CSDN上的很多文檔都沒有介紹,只有一篇關於 C++ Builder 的使用樣本,但是我相信很多用 Delphi 的朋友跟我一樣都會覺太複雜,很難寫成 Delphi 的文法。所以自己就動手做,終於最有實現了!這裡就拿出來跟大家共用。我不能保證我的樣本是優秀,但是確實是可以工作的,我用它在已經發了幾萬個POST請求,沒有出錯。
至於第二個問題,我這裡只是對一個朋友網文的補充,看看如何輕鬆、準確預覽 HTML 片段,相信跟我一樣比較喜歡偷懶、完美的人會喜歡的!
先看看文中用到的幾個 TWebBrowser 的關鍵屬性、方法、事件:
OleObject.Document 屬性:指向 TWebBrower 的文檔介面,也可以用 Document 屬性代替
DefaultInterface 屬性:指向組件的預設介面,也就是 TWebBrower 本身
ReadyState 屬性:指示 TWebBrower 組件的狀態
Navigate 過程:本文用來 POST 資料調用的方法,與 Navigate2 相似,文中用了這個
OnBeforeNavigate2 事件:調用 Navigate 後,真正發送事件前發生,帶來所有 POST 的參數
OnNewWindow2 事件:TWebBrower 組件需要開啟新視窗時發生,可以屏蔽或重定位新視窗
OnDocumentComplete 事件:文檔裝載完畢時發生
下面就來開始我們的第一個例子:
1、所用組件:
wbMain: TWebBrowser;// 主的 TWebBrowser 組件
wbAssistant: TWebBrowser; // 輔助 TWebBrowser 組件,有些網站要求
memoSource: TMemo;// 存放 POST 回來的 HTML 文本
memoLog: TMemo;// 記錄一些 Navigate 的資料
btnPrepare: TBitBtn;// 做些準備操作
btnPost:??? TBitBtn;// 真正 POST 資料出去
2、編寫代碼:
A、準備起始網頁
根據各個網站,可能要求不用,有的網站不要求預先瀏覽網頁就可以直接 POST 資料的,有些不行,還有些必須是重另一個網頁跳轉過來的(下面的例子就是,如果不是這種情況,可以不用 wbAssistant 組件)
procedure TformMain.btnPrepareClick(Sender: TObject);
begin
// 如果網站不要求跳轉可以直接用下面一句,如果不用預覽,則完全不需要準備這個過程的?
// wbMain.Navigate('http://www.imobile.com.cn/pconline2.php');
wbAssistant.Navigate('http://www.hao123.com/haoserver/showjicc.htm');
end;
procedure TformMain.wbAssistantNewWindow2(Sender: TObject;
var ppDisp: IDispatch; var Cancel: WordBool);
begin
// 把新視窗指向 wbMain ,要不就會彈出新視窗,要求此時不能有瀏覽器已經開啟目標頁,要不還是定位在那個視窗(本例)
??? ppDisp := wbMain.DefaultInterface;??
end;
B、發送 POST 資料
????? 對本例需要現在 wbAssistant 輸入一個手機號碼,然後才跳轉到 wbMain,本來可以只用一個瀏覽器,但考慮到本例網站本身要求跳轉到新頁面,就用兩個瀏覽器(實際可以跳轉會原來的)。
????? 下面是關鍵代碼,注意每個參數是怎麼定義的!
procedure TformMain.btnPostClick(Sender: TObject);
var
? Index: Integer;
? URL: WideString;
? Flags, TargetFrameName, PostData, Headers:? OleVariant;
? PostStr: AnsiString;
? PostLen: Integer;
begin
? // 先等待文章裝載好了再進行
? while wbMain.ReadyState <> READYSTATE_COMPLETE??????? do
??? Application.ProcessMessages;
? //========================================================
? // 準備參數
? URL := 'http://www.ip138.com:8080/search.asp';? // 本例
? Flags := 0;???????????????????????? // VarType: varInteger
? TargetFrameName := 'mobilewindow';? // VarType: varOleStr
? // 構建 PostData 資料?????????????? // VarType: 16396? (Variant array of Variant)
? // PostStr 採用 URL 的編碼方式,具體如何變換大家查考相關文檔,這裡假定大家已經清楚
? PostStr := 'mobile=' + editData.Text + '&action=mobile&B1=%B2%E9+%D1%AF';
? PostLen := Length(PostStr);
? // 用構建 varByte 類型的 Variant array
? PostData := VarArrayCreate([0, (PostLen - 1)], varByte);
? // 填充資料
? for Index := 0 to PostLen - 1 do
??? PostData[Index] := Ord(PostStr[Index + 1]);
? // 填補頭部資料注意:application
? Headers := 'Content-Type: application/x-www-form-urlencoded';? // varOleStr
? //========================================================
? // 用 Navigate 方法 POST 資料(如果 PostData 為空白,TWebBrowser 用 GET 方法)
? wbMain.Navigate(URL, Flags,TargetFrameName, PostData, Headers);
? //========================================================
? // 等待接收結果 HTML
? while wbMain.ReadyState <> READYSTATE_COMPLETE??????? do
??? Application.ProcessMessages;
? // 提取資料,可以根據需要用其他方式
? memoSource.Text := wbMain.OleObject.Document.all.tags('HTML').Item(0).outerHTML;
end;
C、可以在事件 OnBeforeNavigate2 檢查資料(可選)
我覺得這個事件很有用,可以用來檢測 TWebBrowser 實際上發送了什麼資料到網路上,如 URL、PostData,我就是通過這個事件才搞清楚到底怎樣構建 PostData 的資料的。
procedure TformMain.wbMainBeforeNavigate2(Sender: TObject;
? const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
? Headers: OleVariant; var Cancel: WordBool);
var
? Index:? Integer;
? PostStr: AnsiString;
begin
// 加入時間標籤
memoLog.Lines.Add(FormatDateTime('==== yyyy-mm-dd hh:nn:ss ====', Now()));
memoLog.Lines.Add('URL: ' + URL);
memoLog.Lines.Add('Flags: ' + IntToStr(Flags));
memoLog.Lines.Add('TargetFrameName: ' + TargetFrameName);
// 注意如何處理 PostData
if Length(PostData) > 0 then
begin
PostStr := 'PostData(' + IntToStr(Length(PostData)) + '): ';
for Index := 0 to VarArrayHighBound(PostData, 1) do
begin
PostStr := PostStr + Chr(Byte(PostData[Index]));
end;
memoLog.Lines.Add(PostStr);
end;
memoLog.Lines.Add('Headers: ' + Headers);
end;
上面就是完整代碼,在 Delphi 7(Window 2000/XP)調試通過!
對於第二問題,我這裡就不詳細介紹,只提兩個關鍵點:
1、用 TWebBrowser 預覽 HTML 片段的方式:
?? HTMLText := '
測試 HTML 片段
// HTMLText 就是要預覽的 HTML 片段
wbMain.Navigate('about:blank');
while wbMain.ReadyState <> READYSTATE_COMPLETE do
Application.ProcessMessages;
wbMain.OleObject.Document.body.innerHTML := HTMLText;?
顯示圖片和Style:
採用上面方式預覽時有個問題,就是相對路徑的圖片、採用Style的格式沒辦法準確顯示。可以這樣處理,例如想分析“www.163.com”首頁的一些片段,可以這樣實現,解決這個問題:
HTMLText := '
測試 HTML 片段
// HTMLText 就是要預覽的 HTML 片段
wbMain.Navigate('www.163.com');
while wbMain.ReadyState <> READYSTATE_COMPLETE do
Application.ProcessMessages;
wbMain.OleObject.Document.body.innerHTML := HTMLText;?
上面就是完整代碼,在 Delphi 7(Window 2000/XP)調試通過!
-----------------------------------------------------------------------------
希望本文章能讓你更好的使用 TWebBrowser!需要例子可以跟我聯絡。
連絡方式:
QQ:4263383
EM:zhengcg@163.com
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=65883