修改 把它缩小到这一行,
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?
答案 0 :(得分:4)
请记住,在导航页面时,OnDocumentComplete可以多次(帧)触发。
如何正确实现OnDocumentComplete:
procedure YourForm.OnDocumentComplete(
Sender: TObject;
const pDisp: IDispatch;
var URL: OleVariant);
var
currentBrowser: IWebBrowser;
topBrowser: IWebBrowser;
document: OleVariant;
windowName: string;
begin
currentBrowser := pDisp as IWebBrowser;
topBrowser := (Sender as TWebBrowser).DefaultInterface;
if currentBrowser = topBrowser then
ShowMessage('Complete document was loaded')
else
begin
document := currentBrowser.Document;
windowName := document.ParentWindow.Name;
ShowMessage(Format('Frame "%s" was loaded', [windowName]));
end;
end;
源:
http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_events.htm#OnDocumentComplete
答案 1 :(得分:2)
您的问题似乎是在尝试获取HTML之前,您不允许TWebBrowser完成页面加载。这只是猜测,因为您没有显示您调用wb.Navigate的代码如何,并且您必须处理获取InnerHTML的异常。
您应该尝试以下方法:
procedure TForm1.GetHTML(URL: string; var HTML: string);
begin
wb.Navigate(URL);
Application.ProcessMessages;
while wb.Busy do
Application.ProcessMessages;
HTML := wb.OleObject.Document.documentElement.innerHTML;
end;
答案 2 :(得分:0)
与@ crefird的回答一样,我怀疑您在浏览器完成其工作之前尝试访问InnerHTML ...
如果ReadState / Busy没有返回TWebBrowser繁忙状态的准确表示,您可以这样做:
1)创建一个全局变量或表单的私有成员...例如“FBrowserBusy:Boolean”(不要忘记在调用之前将其初始化为“.Navigate”) 2)正如@crefird在他的回答中所说,使用“while”循环,只用“wb.Busy”代替“FBrowserBusy”。 3)将OnDocumentComplete事件添加到您的TWebBrowser实例,并将此设置为FBusy:= False;
这将消除任何冲突,并确保TWebBrowser对象在外部例程继续询问之前已完成加载文档。
希望您觉得这很有帮助!