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

Delphi 10.4使用TEdgeBrowser提取网页游戏数据方法咨询

Delphi 10.4 基于TEdgeBrowser提取游戏轮次数据实现方案

目标站点为动态渲染的在线游戏运行页,静态爬取方式无法拿到实时更新的轮次数据,基于TEdgeBrowser(WebView2内核)的JS注入+消息通信能力可以实现稳定采集,具体实现流程如下:

前置配置

  • 确保开发环境已正确安装WebView2运行时,TEdgeBrowser组件可正常加载目标页面。
  • 所有脚本注入逻辑必须在页面完全加载完成后执行,避免因DOM未渲染导致的节点查找失败。
  • 不推荐使用固定间隔轮询DOM的方式采集数据,性能损耗高且延迟大,优先使用DOM变动监听+主动消息推送的方案。

核心实现步骤

1. 页面加载完成后注入数据监听脚本

绑定TEdgeBrowser的OnNavigationCompleted事件,确认页面加载成功后,注入自定义JS脚本,实现两个核心能力:

  • 自动匹配页面中显示总投注额、赔付系数的文本节点
  • 监听DOM变动,数据更新时主动将结构化数据推送到Delphi层
    注入的JS参考代码如下:
// 提取当前页面展示的游戏数据
function fetchCurrentGameData() {
  let totalBet = null;
  let payout = null;
  // 遍历节点匹配目标字段,适配动态class/ID的场景
  document.querySelectorAll('*').forEach(el => {
    const content = el.innerText?.trim() || '';
    if (content.startsWith('Total Bets:')) {
      totalBet = parseFloat(content.replace('Total Bets:', '').trim());
    }
    if (content.startsWith('Payout coefficient:')) {
      payout = parseFloat(content.replace('Payout coefficient:', '').trim());
    }
  });
  return {
    totalBet: totalBet,
    payoutCoefficient: payout,
    updateTime: Date.now()
  };
}

// 注册DOM变动监听器
const domObserver = new MutationObserver(() => {
  const currentData = fetchCurrentGameData();
  // 仅当两个字段都为有效数值时推送消息
  if (!isNaN(currentData.totalBet) && !isNaN(currentData.payoutCoefficient)) {
    window.chrome.webview.postMessage(JSON.stringify(currentData));
  }
});

// 启动全局监听
domObserver.observe(document.body, {
  childList: true,
  subtree: true,
  characterData: true
});

// 首次加载完成主动推送一次初始数据
window.chrome.webview.postMessage(JSON.stringify(fetchCurrentGameData()));

如果游戏运行在iframe嵌套容器内,需要先定位到对应iframe的contentWindow,在iframe的上下文内执行上述脚本,顶层页面直接注入无法读取iframe内部数据。

2. Delphi端接收消息并写入数据表

绑定TEdgeBrowser的OnWebMessageReceived事件,解析前端推送的JSON数据,校验合法性后写入自有数据表即可,参考代码片段:

uses
  System.JSON, System.SysUtils, Data.DB;

procedure TMainForm.EdgeBrowser1NavigationCompleted(Sender: TObject;
  const Args: TNavigationCompletedEventArgs);
var
  LMonitorScript: string;
begin
  // 页面加载成功后注入监听脚本,脚本可存为RC资源避免硬编码
  if Args.IsSuccess then
  begin
    LMonitorScript := LoadResString(RES_GAME_DATA_MONITOR);
    EdgeBrowser1.ExecuteScript(LMonitorScript);
  end;
end;

procedure TMainForm.EdgeBrowser1WebMessageReceived(Sender: TObject;
  const Args: TWebMessageReceivedEventArgs);
var
  LJsonVal: TJSONValue;
  LTotalBet: Double;
  LPayout: Double;
begin
  LJsonVal := TJSONObject.ParseJSONValue(Args.ArgsAsString);
  if not Assigned(LJsonVal) then Exit;
  try
    // 校验字段有效性
    if LJsonVal.TryGetValue<Double>('totalBet', LTotalBet) and
       LJsonVal.TryGetValue<Double>('payoutCoefficient', LPayout) then
    begin
      // 此处执行数据入库逻辑,建议增加去重判断
      // 可通过赔付系数重置特征(新一轮启动时系数回到初始值)区分轮次,避免写入同轮次的中间跳动值
      qryGameStats.Append;
      qryGameStats.FieldByName('total_bet').AsFloat := LTotalBet;
      qryGameStats.FieldByName('payout_coef').AsFloat := LPayout;
      qryGameStats.FieldByName('record_time').AsDateTime := Now;
      qryGameStats.Post;
    end;
  finally
    LJsonVal.Free;
  end;
end;

优化建议

  • 如果页面DOM结构随版本更新频繁变动,可以在注入脚本中重写window.fetch和XMLHttpRequest原型方法,直接拦截游戏前后端通信的接口响应,从接口报文中提取目标字段,不需要依赖DOM结构,长期稳定性更高。
  • 若页面开启了JS上下文隔离导致DOM读取失败,可切换为WebView2的网络请求拦截API,在DevTools协议层监听游戏接口的响应数据,无需注入页面上下文即可拿到数据。

内容的提问来源于stack exchange,提问作者Maurilio Lima Junior

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:54:19