导航
  • 主页
  • 语言基础/算法/系统设计
  • 数据库相关
  • 图形处理/多媒体
  • 网络通信/分布式开发
  • VCL组件开发及应用
  • Windows SDK/API
  • 问答

关于TWebbroser!

kfcoffe 2010-03-01 11:31:12
在尝试用TWebbroser操作网页的时候发现一个奇怪的问题,同样一段代码 放在主线程中能正确执行,但是由于该操作比较耗时就开辟了新的线程 去执行该段代码 ,结果只要一运行该段代码就报错,而且错误随机出现

注 :该段代码主要对TWebBroser操作!


1. 在主线程中,正常

for I := 0 to ListBox1.Items.Count-1 do
begin
Str := trim(ListBox1.Items.Strings[I]);
ListBox1.ItemIndex := I;
if (Length(Str) < 10) or (pos('http://',Str)< 0) then Continue;
WebBrowser4.Navigate(Str) ;
while (Form1.WebBrowser4.ReadyState <> READYSTATE_COMPLETE) do
begin
Application.ProcessMessages;

end;
//sleep(0);


for K := 0 to WebBrowser4.OleObject.Document.all.tags('span').Length - 1 do
begin
str1 := WebBrowser4.oleobject.document.all.tags('span').item(K).innertext;
if ansicontainsstr(str1,'write a comment') then begin
WebBrowser4.oleobject.document.all.tags('span').item(K).click;
break;
end;
end;
//GetElem('span','write a comment');
///////////////////////////////////////////////////////////////////////
if assigned(WebBrowser4) then
begin
doc := WebBrowser4.Document as ihtmldocument2;
ContentArea := doc.all.item('comment',0) as ihtmltextareaelement;
if ContentArea = nil then continue;
ContentArea.value := 'have a Test!';
for K := 0 to WebBrowser4.OleObject.Document.all.tags('span').Length - 1 do
begin
str1 := WebBrowser4.oleobject.document.all.tags('span').item(K).innertext;
if ansicontainsstr(str1,'submit comment') then begin
WebBrowser4.oleobject.document.all.tags('span').item(K).click;
break;
end;
end;

// GetElem('span','submit comment');
end;
end;






2. 在开辟的新线程中,无法执行,报的错误有好几种,随机出现..............


procedure TSendThread.Execute;
var
doc:ihtmldocument2;
ContentArea:ihtmltextareaelement;
I ,K: Integer;
Str,Str1 : string;
begin
for I := FStart to FEnd do
begin
Str := trim(Form1.ListBox1.Items.Strings[I]);
Form1.ListBox1.ItemIndex := I;
if (Length(Str) < 10) or (pos('http://',Str)< 0) then Continue;
Form1.WebBrowser4.Navigate(Str) ;
while (Form1.WebBrowser4.ReadyState <> READYSTATE_COMPLETE) do
begin
Application.ProcessMessages;
if Terminated then Exit;
end;
//sleep(0);

if Terminated then Exit;
for K := 0 to Form1.WebBrowser4.OleObject.Document.all.tags('span').Length - 1 do
begin
str1 := Form1.WebBrowser4.oleobject.document.all.tags('span').item(K).innertext;
if ansicontainsstr(str1,'write a comment') then begin
Form1.WebBrowser4.oleobject.document.all.tags('span').item(K).click;
break;
end;
end;
//GetElem('span','write a comment');
///////////////////////////////////////////////////////////////////////
if assigned(Form1.WebBrowser4) then
begin
doc := Form1.WebBrowser4.Document as ihtmldocument2;
ContentArea := doc.all.item('comment',0) as ihtmltextareaelement;
if ContentArea = nil then continue;
ContentArea.value := 'have a Test!';
for K := 0 to Form1.WebBrowser4.OleObject.Document.all.tags('span').Length - 1 do
begin
str1 := Form1.WebBrowser4.oleobject.document.all.tags('span').item(K).innertext;
if ansicontainsstr(str1,'submit comment') then begin
Form1.WebBrowser4.oleobject.document.all.tags('span').item(K).click;
break;
end;
end;

// GetElem('span','submit comment');
end;
if Terminated then Exit;
end;
end;






思索了好久,在此讨教? 难道是控件和线程同步问题?
...全文
120 点赞 收藏 16
写回复
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
uuxa 2010-12-29
处理的方法是使用Synchronize(someFunction),且someFunction在线程类中定义。
回复
dj2437 2010-03-05
如能在线程里动态创建VCL最好,如不能,一定要操作界面上的VCL那就要加上互拆,或防止同时操作的情况,
否则必然出错
回复
iuIRCClient 2010-03-03
你刚Navigate(str)就去循环检测状态么?直接处理Ondocumentcomplete事件吧,在事件里操作你的页面元素就不费时也不会卡死了。

另外不要在线程中操作vcl,哪怕是showmessage都是有可能出错的
回复
kfcoffe 2010-03-02
引用 12 楼 sqldebug_fan 的回复:
还是要仔细调试软件,分析原因才能有结果。



这个肯定是不可避免地..............期待高人!
回复
kfcoffe 2010-03-01
引用 8 楼 harryfin 的回复:
Delphi(Pascal) code1.access violation at address.. mshtml.Dll Read .......

这个以前试过在多页的情况下,如果网页没加载完就切换到别的页面,会出这个错误


谢谢,这个提示对我很有帮助, 在线程里面TWebbroser 循环打开我先前采集的网址,但是有1个疑问


for ....................... do
begin
Form1.WebBrowser4.Navigate(Str) ;
while (Form1.WebBrowser4.ReadyState <> READYSTATE_COMPLETE) do
begin
Application.ProcessMessages;
if Terminated then Exit;
end;
end;



这里不存在没加载完成就切换到其他页面啊.......我这里只采用单一线程!
回复
Harryfin 2010-03-01

1.access violation at address.. mshtml.Dll Read .......


这个以前试过在多页的情况下,如果网页没加载完就切换到别的页面,会出这个错误
回复
SQLDebug_Fan 2010-03-01
在线程里访问VCL总是会出一些意想不到的错误。
回复
kfcoffe 2010-03-01
引用 4 楼 avan_lau 的回复:
這應該是 線程 安全 問題 ,采用sync



回: sync 这个也试过,我把线程里面处理的代码统统放到主线程中1个procedure 中,然后
Synchronize(form1.common);结果还是一样........
回复
kfcoffe 2010-03-01
引用 2 楼 jpexe 的回复:
检查一下同步问题,可能是在线内容还未加载完全时,就有其它操作在对它进行访问,就可能出现莫名其妙的错误。而放在主线程中时因为是顺序执行所以不会有同步安全问题。



这里明白,当TWebbroser还没加载完成 就去访问里面的内容,这样就会造成不确定错误......
回复
金卯刀 2010-03-01
這應該是 線程 安全 問題 ,采用sync
回复
kfcoffe 2010-03-01
1.access violation at address.. mshtml.Dll Read ........
2.access violation at address..
3. 灾难性故障...
回复
JPEXE 2010-03-01
检查一下同步问题,可能是在线内容还未加载完全时,就有其它操作在对它进行访问,就可能出现莫名其妙的错误。而放在主线程中时因为是顺序执行所以不会有同步安全问题。
回复
Harryfin 2010-03-01
报什么错也列列吧?

【字数补丁.exe】
回复
SQLDebug_Fan 2010-03-01
还是要仔细调试软件,分析原因才能有结果。
回复
wintergoes 2010-03-01

CoInitialize(nil);
//.........
CoUninitialize;

读取某个item的时候先判断它是否为nil
回复
s11ss 2010-03-01
引用 7 楼 sqldebug_fan 的回复:
在线程里访问VCL总是会出一些意想不到的错误。

对,VCL 控件大多不是线程安全的。在非主线程中不提倡访问 VCL 控件。
回复
发动态
发帖子
Delphi
创建于2007-08-02

4805

社区成员

Delphi 开发及应用
申请成为版主
社区公告
暂无公告