SeleniumBasic中的IWebDriver对象的ExecuteScript方法用于执行JavaScript脚本。语法如下

Function ExecuteScript(script As String, [arg0], [arg1], [arg2])

后面3个是可选参数。

调用ExecuteScript大体分为两种情况:无返回值的和有返回值的。

执行无返回值的外部使用Call关键字,例如:

Call WD.ExecuteScript("alert('Hello,ryueifu!')")

alert('Hello,ryueifu!')是JavaScript语法,作用是弹出一个对话框,无返回值。所以外侧使用VBA的Call

另一种是把JavaScript代码执行的结果返回给VBA。例如下面的程序借助JavaScript计算数学题,结果返回给prod:

Dim prod As Integer

prod = WD.ExecuteScript("return 7-4*5")

Debug.Print prod

打印结果是-13

注意:要想从ExecuteScript中得到返回值,在脚本中必须有return关键字!否则返回Nothing

另外,SeleniumBasic的ExecuteScript函数,除了执行的脚本代码以外,还可以最多设置3个可选参数。这些参数与脚本代码中的arguments对号入座。这样可以增强程序的灵活性。

例如:

prod = WD.ExecuteScript("var p=1;p=arguments[2]-arguments[0]*arguments[1];return p", CStr(4), CStr(5), CStr(7))

Debug.Print prod

上述程序的Cstr(4)对应于arguments[0],以此类推。返回的结果仍然是-13。

当然,同一个参数也可以在脚本中被多次访问,例如:

Call WD.ExecuteScript("alert(arguments[0]+'就是'+arguments[0])", Application.UserName)

Excel VBA中的用户名被调用了两次,显示在网页上。

以上是执行JavaScript脚本的基本知识。

下面介绍几个非常实用的JavaScript技术。

利用JavaScript定位元素

通过前面的学习,SeleniumBasic中的FindElement系列方法只能向下查找,也就是说只能查找已知元素包含的子孙元素。而不能得到一个元素的父级、兄弟元素。实际上这个结论是不对的。FindElement系列的8个定位方法,其中根据XPath、CssSelector这两个定位方法,可以用来定位父级、兄弟元素。

不过本节要介绍的是通过JavaScript代码来定位,其理论依据请参考

https://www.w3school.com.cn/jsref/dom_obj_document.asp

https://www.w3school.com.cn/jsref/dom_obj_all.asp

因为JavaScript可以遍历和定位DOM中的元素,SeleniumBasic又可以执行JavaScript脚本,因此可以实现。

下面以遍历百度首页左上角的7个超链接为例讲解。在开发工具中看一下HTML的构成。

可以看到这7个超链接,位于一个div中。因此,先定位到div,然后找到它的第一个儿子、最后一个儿子,前一个儿子后一个儿子,最后一句parentNode返回其儿子的父亲,也就是他本人。

Dim div AsSeleniumBasic.IWebElementDim anchor AsIWebElementSet div = WD.ExecuteScript("return document.getElementById('s-top-left')")Set anchor = WD.ExecuteScript("return arguments[0].firstChild", div)

Debug.Print anchor.textSet anchor = WD.ExecuteScript("return arguments[0].lastChild", div)

Debug.Print anchor.textSet anchor = WD.ExecuteScript("return arguments[0].previousSibling", anchor)

Debug.Print anchor.textSet anchor = WD.ExecuteScript("return arguments[0].nextSibling", anchor)

Debug.Print anchor.textSet anchor = WD.ExecuteScript("return arguments[0].parentNode", anchor)

Debug.Print anchor.text

以上代码中的5个打印语句的结果如下:

注意领会理解上述代码的精髓,ExecuteScript方法中的参数arguments[0]接收的是一个IWebElement对象,然后该函数返回的结果是另一个IWebElement。

通过这个实例,可以看出定位元素毫无问题。

获取和修改网页元素的属性

SeleniumBasic的IWebElement具有GetAttribute方法,可以返回指定属性名称的属性值。

但是JavaScript中的网页元素都有getAttribute和setAttribute,既可以返回又可以设置属性。

众所周知,百度的搜索按钮的HTML定义如下:

在VBA中运行

Set button = WD.FindElementById("su")

Debug.Print WD.ExecuteScript("return arguments[0].getAttribute(arguments[1])", button, "value")

就可以得到它的value属性:百度一下。

同理,运行

Call WD.ExecuteScript("arguments[0].setAttribute(arguments[1],arguments[2])", button, "value", "百度两下")

可以修改其属性,造成按钮文字被修改。

上面这行代码用了3个arguments,把ExecuteScript的用法演绎的淋漓尽致。如果不使用参数,纯粹的JavaScript代码是:

Call WD.ExecuteScript("document.getElementById('su').setAttribute('value','百度三下')")

注意:JavaScript中关键字和函数名严格区分大小写。

调用网页元素的函数和方法

JavaScript中网页元素有众多的函数和方法。

例如下面的程序,自动输入关键字中秋节,自动点击“百度一下”按钮。

WD.URL = "https://www.baidu.com"

WD.ExecuteScript "document.getElementById('kw').value='中秋节'"

WD.ExecuteScript "document.getElementById('su').click()"

也可以把程序中的对象作为参数传递进去,例如下面的程序,把keyword和button传递到脚本中,通过执行脚本就实现了关键字的输入和搜索按钮的点击。

WD.URL = "https://www.baidu.com"

Dim form AsSeleniumBasic.IWebElementDim keyword AsSeleniumBasic.IWebElementDim button AsSeleniumBasic.IWebElementSet form = WD.FindElementById("form")Set keyword = form.FindElementById("kw")Set button = form.FindElementById("su")

WD.ExecuteScript"arguments[0].value='SeleniumBasic';arguments[1].submit()", keyword, button

运行到ExecuteScript那句时,浏览器的样子如下:

另外,HTMLDocument中有InnerHTML和OuterHTML这两个概念,用来返回网页元素的HTML定义。SeleniumBasic中只提供了IWebElement的TagName、Text等,无法返回完整的HTML标签定义。

Set button = WD.FindElementById("su")

Debug.Print WD.ExecuteScript("return arguments[0].outerHTML", button)

以上代码的打印结果是:

而下面这句则返回按钮的父级元素的定义

Debug.Print WD.ExecuteScript("return arguments[0].parentNode.outerHTML", button)

结果为:

操作DOM文档对象

JavaScript中的document对象是网页文档的最顶级对象。各种成员请参考https://www.w3school.com.cn/jsref/dom_obj_document.asp

下面仅仅举一个返回网页当前的Cookie

Debug.Print WD.ExecuteScript("return document.cookie")

总之,JavaScript脚本无处不在,SeleniumBasic中通过ExecuteScript方法既可以把VBA的数据提交到网页,也可以把网页信息获取到VBA中。

追记:获取复数个网页元素

JavaScript中的document对象以及网页元素对象,具有getElementsByTagName等方法(注意复数s),可以返回具有多个元素的集合。

百度首页的form元素的HTML定义如下

可以看到form下面包含很多input标签。下面程序中的ExecuteScript函数返回一个IWebElement数组。在循环中打印每个input的HTML定义。

Set form = WD.FindElementById("form")Dim Elements() AsIWebElement

Elements= WD.ExecuteScript("return arguments[0].getElementsByTagName('input')", form)EraseElements

Elements= form.FindElementsByTagName("input")For i = 0 To UBound(Elements)

Debug.Print WD.ExecuteScript("return arguments[0].outerHTML", Elements(i))Next i

打印结果为:

vba 执行网页javascript_《SeleniumBasic 3.141.0.0 - 在VBA中操作浏览器》系列文章之十九:执行JavaScript脚本...相关推荐

  1. vba 执行网页javascript_Excel中使用JavaScript的方法

    基础篇 Excel的缺省脚本语言是VBA,所以系统的一切接口理论上都是可以通过VBA脚本访问的,而使用其他脚本语言可能只能访问部分功能,这点是需要开发者明确的.但是Javascript脚本的好处是,其 ...

  2. html 自动执行vbs代码,vbs脚本文件执行-网页设计,HTML/CSS

    昨天下载并且安装了updater application block后,需要执行一个deploy.vbs的文件,鄙人才疏学浅,这个小问题竟然也花费了我不少心机. 现在把结论共享一下. 首先,我的vbs ...

  3. vue设置浏览器自动打开网址为 http://0.0.0.0:8080/ 的网页可能暂时无法连接,或者它已永久性地移动到了新网址。

    2022年6月14日,用脚手架创建了vue2项目,设置当项目运行起来的时候,让浏览器自动打开:"serve": "vue-cli-service serve --open ...

  4. vba获取html代码数据,用VBA实现网页数据获取

    做某个学校大作业的时候,需要查接近$500$个数据:手动是不太现实的 于是通过网上冲浪找到了使用VBA的实现方法,在这里稍微总结下 VBA就是Microsoft Office / WPS Office ...

  5. vba打开html文件,vba打开网页的四种方法

    内容提要:文章介绍在excel中vba打开网页的四种方法,分别使用API.SHELL函数.FollowHyperlink方法."InternetExplorer"对象来实现. Q: ...

  6. sqlite-1.0.0源码执行的基本流程概述

    sqlite-1.0.0原理概述 sqlite是一款嵌入式的轻量级的数据库,首个版本诞生于2000年,该数据库遵守ACID的关系数据库管理系统,SQLite不是一个cs架构的数据库引擎,而是被集成在用 ...

  7. wordpress 5.0.0 远程代码执行漏洞分析cve-2019-8943

    近日,wordpress发布一个安全升级补丁,修复了一个WordPress核心中的远程代码执行漏洞.代码修改细节可以参考wordpress团队于Dec 13, 2018提交的代码.据漏洞披露者文中所介 ...

  8. js中当等于最小值是让代码不执行_网页中JS函数自动执行常用三种方法

    本文为大家分享了在网页中JS函数自动执行常用方法,供大家参考,具体内容如下 一.JS方法 1.最简单的调用方式,直接写到html的body标签里面: 2.在JS语句调用: function myfun ...

  9. java应用程序的执行起点是什么方法_Java应用程序的执行起点是____________方法。(3.0分)_学小易找答案...

    [单选题]以下浮点数的定义和初始化中,错误的是________________.(2.0分) [填空题](2.0分) [单选题]下列有关Java程序基本编程规范的说法中,错误的是___________ ...

最新文章

  1. CentOS 关闭、启动网卡
  2. bzoj 1232: [Usaco2008Nov]安慰奶牛cheer【最小生成树】
  3. 运放放大倍数计算公式_19.运算放大器的特性与应用,不得不掌握的知识点(一)...
  4. 2018年房价到底会不会涨!
  5. flutter 刷脸_支付宝刷脸认证 - osc_bkdv2it5的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. 支持位移操作的环形字符串
  7. uml的图与代码的转换——类图
  8. 正式环境docker部署hyperf_HyperLedger/Fabric SDK使用Docker容器镜像快速部署上线
  9. [转帖] BMC安全隐患
  10. 【Hoxton.SR1版本】Spring Cloud Gateway之如何进行限流
  11. 计算机xp系统恢复以前设置,如何设置xp系统一键还原
  12. 个别照片查看器无法显示此图片因为计算机上,在Windows7中打开照片,提示“Windows 照片查看器无法显示此图片,因为计算机上的可用内存可能不足。....”...
  13. 如何给屏幕设置一个充满全屏幕的背景图片
  14. Linux使用shell脚本批量拷贝文件
  15. 集成WEB服务器的蓝牙路由器及低功耗BLE WIFI 网络规划和实施
  16. 计算机视觉(视频追踪检测分类、监控追踪)常用测试数据集
  17. CF577B Modulo Sum(dp,抽屉原理 | bitset优化 | 二进制优化)
  18. CentOS8搭建FTP服务器
  19. 金钱不能买什么读后感_金钱的界限-----读桑德尔《金钱不能买什么》有感
  20. zabbix php ldap支持,安装zabbix时PHP ldap Warning

热门文章

  1. tkinter进阶版——ttk
  2. ffmpeg -filter_complex 段落停顿
  3. 图形 2.4 传统经验光照模型详解
  4. JS判别是否为X以上刘海屏
  5. 修改MFC中AfxMessageBox()函数的对话框标题
  6. 关于滴滴出行APP的一些思考
  7. Darknet实现YoloV3(2)
  8. java项目前端 手机端下载 .xls 文件,手机默认浏览器下载后缀名变成htm 或者 乱码 解决办法
  9. Centos 下Docker容器安装vim
  10. 微信随机红包数详解和算法代码