鸿 网 互 联 www.68idc.cn

Delphi 10.4.1 EdgeBrowser 模拟操作网页方法

来源:互联网 作者:佚名 时间:2021-12-14 17:54
Delphi 10.4.1 EdgeBrowser 模拟操作网页方法以往一直用TWebBrowser 或者 C++ Builder 中的TCcpWebBrowser来写网页模拟操作这两个控件可以使用WebBrowser.OleObject.document、WebBrowser.Document As IHTMLDocument2来实现大部分的操作发现这两者都是依赖于
Delphi 10.4.1 EdgeBrowser 模拟操作网页方法以往一直用TWebBrowser 或者 C++ Builder 中的TCcpWebBrowser来写网页模拟操作这两个控件可以使用WebBrowser.OleObject.document、WebBrowser.Document As IHTMLDocument2来实现大部分的操作发现这两者都是依赖于IE内核,虽然可以设定IE 11内核,但是今年微软公布11月底停止更新了所以可以考虑使用微软推出的Edge浏览器进入正题:Delphi 10.4.1 新增的TEdgeBrowser控件研究了一下发现该控件似乎不再支持像TWebBrowser那样使用IHTMLDocument2方法了Google一下发现几乎没有资料可寻,在GW某个论坛看到说被其他方式代理了,翻了一下Edge类,在类中有这么一个方法:    /// <summary>    ///   Execute JavaScript code from the javascript parameter in the current top level document rendered in the    ///   WebView, even if ScriptEnabled is False    /// </summary>    procedure ExecuteScript(const JavaScript: string);对应回调事件  当 ExecuteScript 执行完成后回调结果给 OnExecuteScript   /// <summary>  ///   Event handler type for the OnExecuteScript event  /// </summary>  TExecuteScriptEvent = procedure (Sender: TCustomEdgeBrowser; AResult: HResult; const AResultObjectAsJson: string) of object;OnExecuteScript 包含两个参数,AResult 返回状态,AResultObjectAsJson 返回数据经过测试发现,AResultObjectAsJson 默认回调过来的数据如果不是Json而是字符串,那么该字符串会被加上双引号,如 “button click success”,AResultObjectAsJson 的返回值经过测试,好像只返回最后一次被赋值的变量或被修改过的元素值方法:下载WebView2的dll支持库放入程序目录下链接:https://pan.baidu.com/s/1ASnrkr8v893egwSoCVNcjg提取码:igjt下载MicrosoftEdgeDev浏览器,安装好桌面会出现Microsoft Edge Dev图标链接:https://pan.baidu.com/s/1OrGtyYpNdM1ph5qNyHFU1Q提取码:acap在这里插入图片描述以上工作做好以后,即可进行开发了1.界面拖入EdgeBrowser控件2.在控件事件中双击OnExecuteScript创建一个回调事件3. EdgeBrowser1.ExecuteScript(‘你的JavaScript脚本’);假定我们打开的页面有这样一个按钮:<input class="class1" id="button1" type="text" value="">那么在我的程序目录下写一个名为 test.js 的文件,保存格式为utf-8,用于修改网页input的value值。JavaScript代码如下:注意脚本不用加<script></script>,加了之后好像无法运行var Result = null; //这个作为最后处理的结果返回值var item = document.getElementById(“button1”);item.velue = “123456”;//OnExecuteScript回调返回 AResultObjectAsJson 的值是 “123456”//如果加上这一条Result = “输入成功”;//那么 OnExecuteScript回调返回 AResultObjectAsJson 的值是 “输入成功”<br>变通一下,将这个脚本写成模板```javascript//用于向页面input元素输入值var Result = null;//这个作为最后处理的结果返回值var idName = "%s";//这个作为你要替换的元素IDvar mValue = "%s";//这个作为你要写入的值var item = document.getElementById(idName );if(item != null){item.focus();item.value = mValue;//这个就是最后OnExecuteScript返回的值,如果没有这一条,那么返回的应该是 item.value 的值Result = "set " + mValue + " success";//当然也可以返回json、整数Result = {"status":true, "text":"输入成功"};}//如果没有设定Result 的值,那么结果返回的肯定是你修改的值定义一个函数用来加载js文件并格式化数据function getJavaScript(ScriptPath:string; Args:array of string);var AList:TStringList;I:Integer;beginAlist:= TStringList.Create;Alist.LoadFromFile(ScriptPath, TEncoding.UTF8);for I := Low(Args) to High(Args) do  begin  //StringReplace函数 需要引用 System.SysUtils    AList.Text := StringReplace(AList.Text, '%s', Args[I], []);  end;Result:= AList.Text;AList.Free;end;读取脚本并运行procedure TForm1.Button1Click(Sender: TObject);var AText:string;beginAText:= getJavaScript('test.js', ['button1', '123456']);EdgeBrowser1.ExecuteScript(AText);end;这样就可以方便的调用JavaScript脚本了需要注意的是EdgeBrowser1.ExecuteScript();不能在线程中调用,如果是匿名线程需这样TThread.Synchronize(TThread.CurrentThread, procedurebeginEdgeBrowser1.ExecuteScript('你的脚本');end);如果是线程,建议在当前单元定义一个全局变量,用于存放OnExecuteScript的返回值写一个线程函数用于运行并等待回调,回调一般执行失败AResultObjectAsJson 的值是null,成功则返回脚本中的值,我测试了一下这样效果很理想,期待有更好的解决办法function TForm1.ExecJavaScript(AScript: string): string;begin  ScriptResult:= '';//全局变量  TThread.Synchronize(TThread.CurrentThread, procedure begin    EdgeBrowser1.ExecuteScript(AScript);  end);  while not TThread.CheckTerminated do  begin    Sleep(50);    if ScriptResult <> '' then break;  end;  Result:= ScriptResult;end;回调procedure TForm1.EdgeBrowser1ExecuteScript(Sender: TCustomEdgeBrowser;  AResult: HRESULT; const AResultObjectAsJson: string);begin  ScriptResult:= AResultObjectAsJson;end;线程中直接调用ExecJavaScript就可以了,可以循环执行,直到结果不为null线程中调用    Script1:= GetJavaScript('setElementValueById.js', ['J_payeeShowAccount', "123456789"]);    while not TThread.CheckTerminated do    begin      Sleep(50);      if ExecJavaScript(Script1) <> 'null' then break;    end;目前好像就只能这样了,流畅度好像比IE要舒服。。。。期待更好的方法。。。。建议使用Json作为返回值,相对来说复杂点,个人比较懒,哈哈。。来源:https://blog.csdn.net/zhou752947/article/details/109542365
网友评论
<