Delphi 10.4中TEdgeBrowser如何按类名获取元素InnerText
TEdgeBrowser 获取指定类名元素InnerText实现方案
TEdgeBrowser 基于 Chromium 内核的 WebView2 运行时,和旧版 IE 内核 TWebBrowser 的 MSHTML COM 接口体系完全不兼容,原有基于 IHTMLDocument2 的 DOM 操作逻辑无法直接复用,最稳定的实现方式是通过 WebView2 内置的脚本执行能力,注入 JavaScript 完成 DOM 查询后序列化返回结果,在 Delphi 端解析即可。
前置注意事项
- 所有 DOM 操作必须等页面完全加载完成后执行,需绑定 TEdgeBrowser 的
OnNavigationCompleted事件,在事件触发且加载成功后再调用查询逻辑 - 代码需引入核心依赖单元:
System.SysUtils、System.Classes、System.JSON、EdgeBrowser、WebView2
核心实现代码
uses System.SysUtils, System.Classes, System.JSON, EdgeBrowser, WebView2; /// <summary> /// 获取TEdgeBrowser中指定CSS类名对应所有元素的InnerText /// </summary> /// <param name="EdgeBrowser">目标TEdgeBrowser控件实例</param> /// <param name="ClassName">要匹配的CSS类名</param> /// <param name="OnResult">查询完成回调,返回匹配到的InnerText列表、匹配总条数</param> procedure GetInnersByClass(EdgeBrowser: TEdgeBrowser; const ClassName: string; OnResult: TProc<TStringList, Integer>); var JSScript: string; begin if not Assigned(EdgeBrowser) or not Assigned(OnResult) then Exit; // 构造DOM查询脚本:匹配所有指定类名的元素,提取innerText后序列化为JSON数组返回 JSScript := Format( 'JSON.stringify(Array.from(document.getElementsByClassName(%s)).map(el => el.innerText))', [QuotedStr(ClassName)] ); // 执行脚本,异步获取返回结果 EdgeBrowser.ExecuteScript(JSScript, procedure(const AResult: string; const AErrorCode: Integer) var ResultList: TStringList; JSONVal: TJSONValue; JSONArr: TJSONArray; I: Integer; MatchCount: Integer; begin ResultList := TStringList.Create; MatchCount := 0; try if AErrorCode = 0 then begin JSONVal := TJSONObject.ParseJSONValue(AResult); try if Assigned(JSONVal) and (JSONVal is TJSONArray) then begin JSONArr := TJSONArray(JSONVal); MatchCount := JSONArr.Count; for I := 0 to MatchCount - 1 do begin ResultList.Add(JSONArr.Items[I].Value); end; end; finally JSONVal.Free; end; end; OnResult(ResultList, MatchCount); except ResultList.Free; raise; end; end ); end;
调用示例
在页面加载完成事件中调用查询方法:
procedure TForm1.EdgeBrowser1NavigationCompleted(Sender: TObject; const IsSuccess: Boolean; const WebErrorStatus: CoreWebView2WebErrorStatus); begin if not IsSuccess then Exit; GetInnersByClass(EdgeBrowser1, 'your-target-classname', procedure(ResultList: TStringList; MatchCount: Integer) var I: Integer; begin try if MatchCount = 0 then begin ShowMessage('未找到匹配类名的元素'); Exit; end; // 处理结果,例如下发到Memo控件 for I := 0 to ResultList.Count - 1 do begin Memo1.Lines.Add(ResultList[I]); end; finally ResultList.Free; // 使用完成后释放结果列表 end; end ); end;
扩展说明
- 如果需要获取元素的
innerHTML而非innerText,仅需把JS脚本中的el.innerText替换为el.innerHTML即可 - 如果需要支持更复杂的查询规则(比如按ID、层级选择器匹配),可以把JS中的
getElementsByClassName替换为document.querySelectorAll,传入对应CSS选择器即可 - 若使用的TEdgeBrowser版本较旧,
ExecuteScript方法签名可能存在差异,对照当前版本的WebView2接口声明调整参数即可,核心注入JS查询+序列化返回+本地解析JSON的逻辑不变 - 跨域iframe内的元素默认无法直接查询,需要额外配置WebView2跨域访问权限才可读取,普通单页面场景无需额外配置。
内容的提问来源于stack exchange,提问作者Maurilio Lima Junior
相关产品推荐
相关产品推荐

