Chromium(Delphi):访问DOM,如何避免异步,等待页面加载?

时间:2013-11-01 23:34:07

标签: delphi dom chromium tchromium

我是TChromium的新手。我收集了具体的示例代码,制作了自己的测试程序。现在我遇到了一些问题,我希望有人能帮助我解决问题:
首先。我正在使用OnLoadEnd来捕捉页面加载的时刻,但它无法正常工作。至少我的代码如下。如何正确捕捉那一刻?
只要VisitDom是异步的,我就无法在加载页面之后以及在循环中加载下一页之前如何调用它。要么!如果逐页加载每个页面就可以了,并且对于每个加载页面的DOM快照执行异步VisitDom 比。与脚本类似的情况(尚未在我的测试程序中实现)。在加载后的每个页面上都会有脚本执行,DOM会被更改,所以我也需要解析它。请帮助我解决任何问题:在脚本完成时捕获,然后在它之后立即解析页面或者完成scirpt并完成解析页面异步完全由此脚本生成的DOM。

缩短周期如下:  加载页面  页面加载
 解析这个 DOM  执行脚本
 脚本执行
 解析这个 DOM 其中parse DOM可以在循环中执行,也可以在特定时刻与确切的DOM异步执行。

简化问题如下:如何捕获事件'页面加载'和'脚本完成',以及如何访问在此特定时刻精确生成的DOM快照(同步或异步)

感谢您的帮助!

type
  TElementNameVisitor = class(TCefDomVisitorOwn)
  private
    FMemo: TMemo;
  protected
    procedure visit(const document: ICefDomDocument); override;
  public
    constructor Create(AMemo:TMemo); reintroduce;
  end;


implementation

constructor TElementNameVisitor.Create(AMemo:TMemo);
begin
  inherited Create;
  FMemo := AMemo;
end;

procedure TElementNameVisitor.Visit(const document: ICefDomDocument);
  procedure ProcessNode(ANode: ICefDomNode);
  var
    Node: ICefDomNode;
  begin
    if Assigned(ANode) then
    begin
      Node := ANode.FirstChild;
      while Assigned(Node) do
      begin
        if Node.ElementTagName='DIV' then
        begin
          if Node.GetElementAttribute('id')='type-tabs' then
            FMemo.Lines.Add('FOUND');
        end;
        ProcessNode(Node);
        Node := Node.NextSibling;
      end;
    end;
  end;

begin
  FMemo.Lines.Add('START');
  ProcessNode(document.Body);
end;

procedure ProcessElementsByName(const AFrame: ICefFrame; AMemo:TMemo);
var
  Visitor: TElementNameVisitor;
begin
  if Assigned(AFrame) then
  begin
    Visitor := TElementNameVisitor.Create(AMemo);
    AFrame.VisitDom(Visitor);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Links:TStringList;
    i:integer;
begin
  Links:=TStringList.Create;
  Memo1.Lines.Clear;

  Links.Add('www.link1.com');
  Links.Add('www.link2.com');
  Links.Add('www.link3.com');

  for i:=0 to Links.Count-1 do begin
    Chromium1.Load(Links.Strings[i]);
    repeat Application.ProcessMessages until FLoaded;
    Memo1.Lines.Add('Loaded #'+IntToStr(i));
    for j := 0 to 20 do begin
      Sleep(100); Application.ProcessMessages;
    end;
    ProcessElementsByName(Chromium1.Browser.MainFrame, Memo1);
    for j := 0 to 20 do begin
      Sleep(100); Application.ProcessMessages;
    end;
  end;

  Memo1.Lines.Add('end of btnClick');
end;

procedure TForm1.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
  const frame: ICefFrame; httpStatusCode: Integer; out Result: Boolean);
begin
  FLoaded:=True;
end;

procedure TForm1.Chromium1LoadStart(Sender: TObject; const browser: ICefBrowser;
  const frame: ICefFrame);
begin
  FLoaded:=False;
end;

0 个答案:

没有答案