You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CEF4Delphi页面滚动后无法获取更新后的HTML内容求助

解决CEF4Delphi滚动加载后无法获取更新HTML的问题

问题根源

你使用的MainFrame.GetSourceProc、RetrieveHTML这类方法,获取的是浏览器从服务器接收到的原始HTML源码,而非当前页面的DOM快照。wp.pl/onet.pl这类网站通过JavaScript动态修改DOM实现滚动加载,动态新增的元素不会改变原始HTML源,所以你拿到的始终是初始内容。

正确解决方案:通过JS获取当前DOM并回调到Delphi

要获取更新后的完整页面内容,必须在浏览器JS上下文里抓取当前DOM的HTML,再通过CEF进程间通信传递回Delphi端。

1. 配置进程消息接收事件

确保TChromium组件的OnProcessMessageReceived事件已正确实现,用于接收JS发送的消息:

procedure TForm1.Chromium1ProcessMessageReceived(Sender: TObject;
  const browser: ICefBrowser; const frame: ICefFrame;
  sourceProcess: TCefProcessId; const message: ICefProcessMessage;
  out Result: Boolean);
begin
  Result := False;
  if message.Name = 'DOMContent' then
  begin
    // 接收JS传递的完整HTML
    html_result := message.ArgumentList.GetString(0);
    Result := True;
  end;
end;

2. 执行JS获取DOM并发送消息

使用CEF4Delphi内置的JS全局函数,直接抓取当前DOM并发送到Delphi主进程:

// 在需要获取HTML时执行这段代码
Form1.Chromium1.Browser.MainFrame.ExecuteJavaScript(
  '// 获取当前页面完整DOM的HTML' +
  'var fullHtml = document.documentElement.outerHTML;' +
  '// 创建进程消息' +
  'var msg = cefCreateProcessMessage("DOMContent");' +
  '// 添加HTML内容到消息参数' +
  'msg.argList.setString(0, fullHtml);' +
  '// 发送到浏览器主进程(Delphi端)' +
  'cefSendProcessMessage(PID_BROWSER, msg);',
  '', // 留空自动使用当前页面上下文URL
  0
);

3. 等待滚动加载完成再执行

滚动后需要等待动态内容加载完毕,避免获取不完整的DOM。可以用以下两种方式:

方式一:简单延迟(适合测试)

// 先滚动到页面底部
Form1.Chromium1.ExecuteJavaScript('window.scrollTo(0, document.body.scrollHeight);', '', 0);
// 延迟3秒后获取DOM(根据网站加载速度调整)
TThread.Synchronize(nil, procedure
begin
  // 执行上面的获取DOM的JS代码
  Form1.Chromium1.Browser.MainFrame.ExecuteJavaScript(
    'var fullHtml = document.documentElement.outerHTML;' +
    'var msg = cefCreateProcessMessage("DOMContent");' +
    'msg.argList.setString(0, fullHtml);' +
    'cefSendProcessMessage(PID_BROWSER, msg);',
    '',
    0
  );
end);

方式二:监听DOM变化(更严谨)

通过JS的MutationObserver监听DOM新增元素,确认内容加载完成后再发送HTML:

Form1.Chromium1.Browser.MainFrame.ExecuteJavaScript(
  '// 滚动到底部' +
  'window.scrollTo(0, document.body.scrollHeight);' +
  '// 监听DOM变化' +
  'var observer = new MutationObserver(function(mutations) {' +
  '  // 判断是否新增了文章元素(根据目标网站的DOM结构调整)' +
  '  var hasNewContent = mutations.some(function(mutation) {' +
  '    return mutation.addedNodes.length > 0 && ' +
  '           Array.from(mutation.addedNodes).some(node => node.tagName === "ARTICLE");' +
  '  });' +
  '  if (hasNewContent) {' +
  '    observer.disconnect();' +
  '    var fullHtml = document.documentElement.outerHTML;' +
  '    var msg = cefCreateProcessMessage("DOMContent");' +
  '    msg.argList.setString(0, fullHtml);' +
  '    cefSendProcessMessage(PID_BROWSER, msg);' +
  '  }' +
  '});' +
  '// 监听body下所有子元素变化' +
  'observer.observe(document.body, { childList: true, subtree: true });',
  '',
  0
);

之前方法失效的原因

  • cefQuery需要提前在Delphi端实现OnQueryRequest事件,且调用格式严格,未配置的话不会触发回调
  • 自定义的cef.createMessage不是CEF4Delphi内置函数,无法被识别执行

内容的提问来源于stack exchange,提问作者kwadratens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:11:18