使用 VBA 自动化 Chrome / Edge

介绍

Internet Explorer classic(下称IE)是基于ActiveX技术的。对于 Webscraping 或从 VBA 等 OLE 感知编程语言进行测试等任务,自动化 IE 非常容易。但微软将在不久的将来终止对 IE 的支持,并希望用户转向 Microsoft Edge 等更新的浏览器。

Microsoft Edge 不再基于 ActiveX 技术。Microsoft 似乎对创建 IE OLE 对象的替代品不感兴趣。有一些库试图使用 Selenium 来填补这个空白,请参阅Seleniumbasic作为示例。但这需要安装 Webdriver,这在某些环境中可能不可行。除了基于 Chrome 的浏览器之外,以下解决方案不需要其他软件。

请记住,在运行代码之前必须终止所有正在运行的 Edge 进程。否则,选项卡将在当前运行的进程中打开,而不是在已启动的进程中打开,并且 VBA 和 Edge 之间的后续通信将失败。

CDP 协议

该代码使用 Chrome Devtools 协议 (CDP) 与浏览器进行通信。可以在此处找到该协议的完整文档。该代码仅实现了一组非常狭窄的功能:

  1. 建立通讯通道的基本功能
  2. 导航到 url
  3. 评估页面上下文中的任意 JavaScript 表达式并返回结果

但是这些功能应该足以进行基本的 Webscraping。主要代码如下:

VB.NET
收缩▲   

该类clsEdge实现 CDP 协议。CDP 协议是基于消息的协议。消息被编码为 JSON。要生成和解析 JSON,代码使用此处的 VBA-JSON 库。

与管道的低级通信

对 CDP 协议的低级访问可通过两种方式获得:Edge 在特定端口或通过管道启动小型 Web 服务器。网络服务器缺乏任何安全功能。计算机上的任何用户都可以访问网络服务器。这可能不会对单用户计算机或专用虚拟容器造成任何风险。但是,如果进程在具有多个用户的终端服务器上运行,则这是不可接受的。这就是代码使用管道与 Edge 通信的原因。

Edge 使用第三个文件描述符 (fd) 读取消息,使用第四个 fd 写入消息。将 fds 从父进程传递给子进程在 Unix 下很常见,但在 Windows 下不常见。用于创建子进程 ( CreateProcess) 的 WinApi 调用允许使用该结构为三个常见的 fds ( stdinstdout, ) 设置管道,请参阅CreateProcessA 函数 (processthreadsapi.h)STARTUPINFOA 结构 (processthreadsapi.h)。其他 fds 不能传递给子进程。stderrSTARTUPINFO

为了设置第四个和第五个 fds,必须使用 Microsoft Visual C Runtime ( MSVCRT) 的一个未记录的特性:如果应用程序是用 Microsoft C 编译的,则可以使用结构的lpReserved2参数传递管道STARTUPINFO。有关详细信息,请参阅“未记录的CreateProcess ”(向下滚动页面)。

可以传入的结构lpReserved2在模块中定义modExec

VB.NET

该结构被定义为传递os_handle数组中的五个 fd。数组的值crt_flags可以从libuv/process-stdio.c at v1.x · libuv/libuv · GitHub获得。必须的字段struct连续位于内存中(打包)。VBA 将struct字段对齐到 4 字节边界(在 32 位系统上)。这就是为什么struct定义第二个原始类型的原因。

VB.NET

填充 后STDIO_BUFFER struct,内容被复制MoveMemorySTDIO_BUFFER2结构中。25 个字节的大小足以容纳crt_flags(5 个字节)和指针(20 个字节)。 

历史

猜你喜欢

转载自blog.csdn.net/wouderw/article/details/127643608