相信 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,本来可以只用一个浏览器,但考虑到本例网站本身要求跳转到新页面,就用两个浏览器(实际可以跳转会原来的)。
????? 下面是关键代码,注意每个参数是怎么定义的!
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 的数据的。
? 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