2

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

更短的周期看起来像: 加载页面
加载页面
解析这个DOM执行
脚本
执行的脚本
解析这个DOM可以在循环的时刻执行,也可以在特定时刻与确切的 DOM 异步执行
parse 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;
4

0 回答 0