相信 Delphi 中 TWebBrowser 组件大家都比较熟悉,用它自己进行制作浏览器非常简单,论坛中和文档中心中都谈了很多,我这里主要想谈两个两个问题:
如何用 TWebBrowser 组件 POST 数据?
如何用 TWebBrowser 组件预览 HTML 文档片段?
因为工作需要,需用用到 TWebBrowser 组件的 POST 功能,查了优快云上的很多文档都没有介绍,只有一篇关于 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.youkuaiyun.com/TrackBack.aspx?PostId=65883
588

被折叠的 条评论
为什么被折叠?



