尝试访问 TWebbrowsers HTML 时应用程序锁定
编辑 把它缩小到这1行,
HTML := wb.OleObject.Document.documentElement.innerHTML;
这会消耗时间......那怎样才能加快速度呢?
使用以下代码,我的应用程序在尝试访问页面的 HTML (Delphi XE) 时可能会挂起 1-2 秒。
function Button1Click(Sender : TObject);
begin
wb.navigate('http://10.0.0.154/stats');
// Use a timer to poll the page - dont wait and process app messages
timer1.enabled := true;
end;
procedure Timer1Timer(Sender : TObject);
var
HTML : WideString;
begin
If GetHTML(HTML) = true then
begin
Timer1.enabled := false;
{ do something }
end;
end;
function GetHTML(var HTML : WideString) : boolean;
var
Document : IHTMLDocument2;
begin
HTML := '';
Result := false;
Document := wb.DOcument as IHTMLDocument2;
If Assigned(Document) then
begin
try
HTML := wb.OleObject.Document.documentElement.innerHTML;
Result := true;
except
Result := false;
end;
end;
end;
但是我注意到在我的 GetHTML 方法中可能需要 1-2 秒才能返回某些内容,并且它会锁定 UI。使用 Delphi XE 查看 AQTime,它表示方法调用很慢(1-2 秒)。它是零星的,我想知道当页面仍在加载中时它是否会失败。
我正在加载的页面是一个内部页面,充满了 javascript,大小为 500k,我无法使用 OnDocumentComplete,因为它在页面准备好之前就触发了,即使我对 ReadyState 进行检查,它仍然会提前触发。
任何人都可以阐明,如果他们有一种更快的方式我可以访问 TWebbrowser 的 HTML?
Edit
Narrowed it down to this 1 line,
HTML := wb.OleObject.Document.documentElement.innerHTML;
which consumes the time... how can that be speed up?
Using the following code my application can hang for 1-2 seconds while it tries to access the HTML of a page (Delphi XE).
function Button1Click(Sender : TObject);
begin
wb.navigate('http://10.0.0.154/stats');
// Use a timer to poll the page - dont wait and process app messages
timer1.enabled := true;
end;
procedure Timer1Timer(Sender : TObject);
var
HTML : WideString;
begin
If GetHTML(HTML) = true then
begin
Timer1.enabled := false;
{ do something }
end;
end;
function GetHTML(var HTML : WideString) : boolean;
var
Document : IHTMLDocument2;
begin
HTML := '';
Result := false;
Document := wb.DOcument as IHTMLDocument2;
If Assigned(Document) then
begin
try
HTML := wb.OleObject.Document.documentElement.innerHTML;
Result := true;
except
Result := false;
end;
end;
end;
However I notice in my GetHTML method can take 1-2 seconds to return something and it locks UI. Looking at the AQTime with Delphi XE it says that method call is slow (1-2 seconds). It's sporatic and I wonder if it fails when the page is still mid load.
The page I am loading is an inhouse page, full of javascript and 500k big, I can't use the OnDocumentComplete because it fires before the page is even ready, even if I do a check on the ReadyState it still fires to early.
Anyone able to shed some light, if their a faster way I can access the HTML of TWebbrowser?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
请记住,导航页面时,OnDocumentComplete 可以触发多次(帧)。
如何正确实现 OnDocumentComplete:
来源:
http://www.cryer .co.uk/brian/delphi/twebbrowser/twebbrowser_events.htm#OnDocumentComplete
Please remember that OnDocumentComplete can fire multiple times (frames) when navigating a page.
How to properly implement OnDocumentComplete:
source:
http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_events.htm#OnDocumentComplete
您的问题似乎是您不允许 TWebBrowser 在尝试获取 HTML 之前完成页面的加载。这只是一个猜测,因为您没有显示调用 wb.Navigate 的代码,并且您必须处理获取 InnerHTML 的异常。
您应该尝试以下操作:
Your problem appears to be that you are not allowing TWebBrowser to complete the loading of the page before you try to get the HTML. This is only a guess because you do not show how the code where you call wb.Navigate and you are having to deal with exceptions getting the InnerHTML.
You should try the following:
与 @crefird 的答案一样,我怀疑您正在尝试在浏览器完成其工作之前访问 InnerHTML...
如果 ReadState/Busy 没有返回 TWebBrowser 繁忙状态的准确表示,您可以执行以下操作:
1)创建一个全局变量,或表单的私有成员...例如“FBrowserBusy:布尔值”(不要忘记在调用之前将其初始化为 TRUE “.导航”)
2)正如@crefird在他的回答中所演示的,使用“while”循环,仅用“wb.Busy”替换“FBrowserBusy”。
3) 添加一个 OnDocumentComplete 事件到你的 TWebBrowser 实例,并设置 FBusy := False;
这将消除任何冲突,并确保 TWebBrowser 对象在外部例程继续询问文档之前已完成加载文档。
希望您觉得这有帮助!
As with @crefird's answer, I suspect you are attempting to access the InnerHTML before the browser has completed its work...
If ReadState/Busy are not returning accurate representations of the TWebBrowser's busy state, you can do this:
1) Create either a global variable, or a private member of your form... such as "FBrowserBusy: Boolean" (DON'T FORGET TO INITIALIZE IT TO TRUE JUST PRIOR TO CALLING ".Navigate")
2) As @crefird demonstrated in his answer, use a "while" loop, only substitute "wb.Busy" for "FBrowserBusy".
3) Add an OnDocumentComplete event to your TWebBrowser instance, and have this set FBusy := False;
This will eliminate any collision, and ensure that the TWebBrowser object has completed loading the document before your outer routine proceeds to interrogate it.
Hope you find this helpful!