【问题标题】:Automating Edge Browser using VBA without downloading Selenium使用 VBA 自动化 Edge 浏览器,无需下载 Selenium
【发布时间】:2022-05-17 07:56:33
【问题描述】:

我有针对 IE 编写的自动化工具。现在,我想通过将“Microsoft Edge”视为默认浏览器来重写这些相同的工具。除了下载作为 Selenium 包一部分的 WebDriver 之外,我找不到替代方法。

有人可以在不下载/安装其他软件或 Web 驱动程序的情况下帮助我自动化 Edge 浏览器吗?

谢谢, 坎蒂

【问题讨论】:

  • 您好,请问这个问题呢? my answer below 对解决问题有帮助吗?如果您有任何其他问题,我很乐意为您提供帮助。

标签: selenium microsoft-edge browser-automation


【解决方案1】:

现在有很多方法可以实现这一点。

方法一

从 2022 年 4 月 25 日起,您现在可以使用 VBA 直接自动化 Edge IE 模式,而无需任何额外的第三方软件。在与我们的合作伙伴 Microsoft 支持团队交流后,我和我的同事对以下指南进行了很好的测试。

你需要做什么

  1. 您的 Windows 版本需要至少为 20H2。您可以通过本指南here查看您的 Windows 版本。

  2. 您的 Windows 需要安装以下 KB:KB5011487。或者只是更新您的 Windows,这也应该会自动安装。您可以通过本指南here 查看您的 Windows 更新历史记录。

  3. 最后在您的 Windows 上安装以下注册表项并重新启动:

    Windows 注册表编辑器 5.00 版

    [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Main] "NotifyDisableIEOptions"=dword:00000002

    [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode] "EnableGlobalWindowListInIEMode"=dword:00000001

根据 MS 支持团队的说法,上述方法应该可以使用到 2029 年。我相信这方面的官方文档可能很快就会发布。

完成上述步骤后,VBA 应该能够与 Edge IE Mode 交互,就好像它是一个 Internet Explorer 窗口一样。您当前的自动化 InternetExplorer.Application 对象的代码也适用于 Edge IE 模式。

方法二

您还可以使用 CodeProject 的 ChrisK23 编写的以下方法,该方法利用 Chrome Devtools 协议与基于 Chromium 的浏览器进行交互。这种方法的优点是它允许 VBA 在没有 IE 模式的情况下直接与 Edge 交互,也可以与 Chrome 交互。

Automate Chrome / Edge using VBA via CDP - Code Project

上面的文章还包括一个示例文件,您可以下载并探索该方法。但是,请注意示例文件缺少 Microsoft Scripting Runtime 参考,您需要在之后手动将其包含在内以使其正常工作。

使用这种方法,您现在甚至可以在不安装其他软件的情况下自动化 Chrome。

方法3

另一种方法是使用 winAPI 从正在运行的 Edge IE 模式窗口的 Internet Explorer Server 类中检索 HTML 文档对象。

Sample Code 1 Sample Code 2

注意:以上代码适用于 Office 32 位。对于 Office 64 位,您需要对其进行转换(有关详细信息,请参阅此 MSDN link

这种方法的优点是它非常干净,并且无需任何额外的设置或安装即可与 Edge IE 模式很好地交互。

缺点是它适用于 Edge IE 模式。因此,仅在 Edge 而不是 IE 模式下运行的 Web 应用程序将无法使用此方法实现自动化。此外,就像方法 1 一样,它的寿命取决于微软将为 Edge 保留 IE 模式多长时间,目前该模式将持续到 2029 年。除此之外,微软可能会也可能不再支持 IE 模式。

【讨论】:

  • 你会写和IE一样的代码吗?例如。你会通过 ieframe.dll (MS Internet Controls) 实例化 Internet.Explorer 的实例吗?
  • @QHarr 是的,您可以保留以前自动化 InternetExplorer 对象的相同 VBA 代码。它在 Edge IE 模式下也是如此。
【解决方案2】:

你可以使用 webdrivermanager 包。因为下面是依赖:

对于 Maven

<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>4.4.3</version>
</dependency>

对于 Gradle:

implementation group: 'io.github.bonigarcia', name: 'webdrivermanager', version: '4.4.3'

您可以在您启动浏览器的课程中使用以下代码:

WebDriverManager.edgedriver().setup()

【讨论】:

  • 嗨 Sonali,我对这个话题非常陌生。在您响应设置边缘驱动程序后,我进行了很多研究。但是,您能否帮助我更多地了解如何实现此驱动程序管理。目前,我已经安装了 SeleniumBasic 包并安装了与我的机器中的边缘浏览器兼容的 msedgedriver.exe。我的问题:我如何使用上面的代码来动态检查边缘驱动程序和边缘浏览器的发行版和版本,而无需手动下载。我正在使用 Excel 的 VBA 编辑器。请帮忙...
  • 请通过wendriver manager代码。编写代码是为了动态检测浏览器版本并根据提供的浏览器名称提供驱动程序。
  • 这是为 Java 而不是 VBA 自动化?
【解决方案3】:

您可以考虑使用 Win API 来实现 Edge 自动化。它不需要任何安装和定期更新 Edge 驱动程序。请参阅我在 Edge 浏览器网页自动化上使用 Win API 的经验:

  1. 将以下代码放入新的空白模块中。我通常将此模块命名为“MsEdge”。本模块中的代码无需修改即可使用。即使对 Win API 不太了解,也可以直接使用代码。

    Public lngProcessID_Close As Long
    
    'Part 1 --- Locate IES
    
    Private strHwndIES As String
    
    Private lngHwndIndex As Long
    
    Private Declare Function EnumWindows Lib "user32" ( _
        ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    
    Private Declare Function EnumChildWindows Lib "user32" ( _
        ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" ( _
        ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    
    'Part 2 --- Get HTMLDocument from IES
    
    Private Const SMTO_ABORTIFHUNG = &H2
    
    Private Const GUID_IHTMLDocument2 = "{332C4425-26CB-11D0-B483-00C04FD90119}"
    
    Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" ( _
        ByVal lpString As String) As Long
    
    Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" ( _
        ByVal hWnd As Long, _
        ByVal msg As Long, _
        ByVal wParam As Long, _
        lParam As Any, _
        ByVal fuFlags As Long, _
        ByVal uTimeout As Long, _
        lpdwResult As Long) As Long
    
    Private Declare Function IIDFromString Lib "ole32" ( _
        lpsz As Any, lpiid As Any) As Long
    
    Private Declare Function ObjectFromLresult Lib "oleacc" ( _
        ByVal lResult As Long, _
        riid As Any, _
        ByVal wParam As Long, _
        ppvObject As Any) As Long
    
    'Part 3 --- Check Process Name
    
    Private Declare Function GetWindowThreadProcessId Lib "user32" ( _
        ByVal hWnd As Long, lpdwProcessId As Long) As Long
    
    
    Public Function findEdgeDOM(Title As String, URL As String) As Object
    
        'Find criteria-hitting Edge page in IE mode
    
        Dim hwndIES As Long
    
        Do
    
            hwndIES = enumHwndIES
    
            If hwndIES Then
    
                Set findEdgeDOM = getHTMLDocumentFromIES(hwndIES)
    
                If InStr(findEdgeDOM.Title, Title) * InStr(findEdgeDOM.URL, URL) Then
    
                    Do
    
                        hwndIES = enumHwndIES
    
                    Loop While hwndIES
    
                    Exit Function
    
                Else
    
                    Set findEdgeDOM = Nothing
    
                End If
    
            End If
    
        Loop While hwndIES
    
    End Function
    
    Public Function enumHwndIES() As Long
    
        'Get all hwnds of IES
    
        If Len(strHwndIES) = 0 Then
    
            EnumWindows AddressOf EnumWindowsProc, 0
    
            lngHwndIndex = 0
    
        End If
    
        'Exit function when overflow
    
        If lngHwndIndex + 1 > (Len(strHwndIES) - Len(Replace(strHwndIES, ",", ""))) Then
    
            enumHwndIES = 0
    
            strHwndIES = ""
    
            Exit Function
    
        End If
    
        'Return IES hwnd one by one
    
        enumHwndIES = CLng(Split(Left(strHwndIES, Len(strHwndIES) - 1), ",")(lngHwndIndex))
    
        lngHwndIndex = lngHwndIndex + 1
    
    End Function
    
    Private Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
    
        Dim lngProcessID As Long
    
        GetWindowThreadProcessId hWnd, lngProcessID
    
        EnumChildWindows hWnd, AddressOf EnumChildProc, lngProcessID
    
        EnumWindowsProc = True
    
    End Function
    
    Public Function EnumChildProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
    
        Dim strTargetClass As String, strClassName As String
    
        strTargetClass = "Internet Explorer_Server"
    
        strClassName = getClass(hWnd)
    
        If strClassName = strTargetClass Then
    
            If GetObject("winmgmts:").ExecQuery("Select Name from Win32_Process WHERE ProcessId='" & lParam & "' AND Name='msedge.exe'").Count Then
    
                strHwndIES = strHwndIES & hWnd & ","
    
                lngProcessID_Close = lParam
    
                EnumChildProc = False
    
                Exit Function
    
            End If
    
        End If
    
        EnumChildProc = True
    
    End Function
    
    Private Function getClass(hWnd As Long) As String
    
        Dim strClassName As String
    
        Dim lngRetLen As Long
    
    
        strClassName = Space(255)
    
        lngRetLen = GetClassName(hWnd, strClassName, Len(strClassName))
    
        getClass = Left(strClassName, lngRetLen)
    
    End Function
    
    Public Function getHTMLDocumentFromIES(ByVal hWnd As Long) As Object
    
        Dim iid(0 To 3) As Long
    
        Dim lMsg As Long, lRes As Long
    
        lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT")
    
        SendMessageTimeout hWnd, lMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes
    
        If lRes Then
    
            IIDFromString StrPtr(GUID_IHTMLDocument2), iid(0)
    
            ObjectFromLresult lRes, IID_IHTMLDocument, 0, getHTMLDocumentFromIES
    
        End If
    
    End Function
    
    Public Sub closeEdge(Title As String, URL As String)
    
        'Close a Edge browser (the last one in EnumWindows order) with criteria-hitting webpage
    
        lngProcessID_Close = 0
    
        Dim findEdgeDOM As Object
    
        Dim hwndIES As Long
    
        Do
    
            hwndIES = enumHwndIES
    
            If hwndIES Then
    
                Set findEdgeDOM = getHTMLDocumentFromIES(hwndIES)
    
                If InStr(findEdgeDOM.Title, Title) * InStr(findEdgeDOM.URL, URL) Then
    
                    Shell "TaskKill /pid " & lngProcessID_Close
    
                    Do
    
                        hwndIES = enumHwndIES
    
                    Loop While hwndIES
    
                    Exit Sub
    
                End If
    
            End If
    
        Loop While hwndIES
    
    End Sub
    
  2. 应用“MsEdge”模块中的功能。有几个应用示例供您参考。建议在另一个模块中放置和测试以下代码:

    Sub findEdgeDOM_DemoProc()
    
        'Demo Proc : Use findEdgeDOM Function to get DOM of specific Edge webpage by Title AND URL
    
        'Dim docHTML As MSHTML.HTMLDocument     '--- Early Binding
    
        Dim docHTML As Object                   '--- Late Binding
    
        Set docHTML = findEdgeDOM("Enter Part of Webpage Title Here", "Enter Part of Webpage URL Here")
        ‘You can fill just one argument with either part of webpage title or URL as keyword to search for the target browser and leave another one blank (“”). If you provide both title and URL, the funcitons return DOM of the only browser that meets both criteria.
    
        If Not docHTML Is Nothing Then Debug.Print docHTML.Title, docHTML.URL
    
    End Sub
    
    Sub goEdge()
    
        'Go through every Edge webpage (opened in IE mode) and print out hwndIES, webpage Title & webpage URL
    
        Dim hwndIES As Long
    
        'Dim docHTML As MSHTML.HTMLDocument     '--- Early Binding
    
        Dim docHTML As Object                   '--- Late Binding
    
        Do
    
            hwndIES = enumHwndIES
    
            If hwndIES Then
    
                Set docHTML = getHTMLDocumentFromIES(hwndIES)
    
                Debug.Print hwndIES, docHTML.Title, docHTML.URL
    
            Else
    
                Debug.Print "Procedure End"
    
            End If
    
        Loop While hwndIES
    
    End Sub
    
    Sub openEdgeByURL_DemoProc()
    
        'Open Edge browser to specific URL
    
        openEdgeByURL "Input Webpage URL Here"
    
    End Sub
    
    Public Sub openEdgeByURL(URL As String)
    
        'Please change the path to your msedge.exe location in your PC
    
        Shell "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe -url " & URL, vbNormalFocus
    
    End Sub
    
    Sub closeEdge_DemoProc()
    
        'Close Edge browser
    
        closeEdge "Enter Part of Webpage Title Here", "Enter Part of Webpage URL Here"
    
    End Sub
    

【讨论】:

    【解决方案4】:

    您使用的是哪个版本的 Selenium?如果您使用的是 Selenium 3 或 Selenium 4,可用的语言有 Java、Python、C#、Ruby 和 JavaScript。您可以参考this doc了解更多信息。

    如果你想在 VBA 中使用 Selenium 来自动化 Edge,你只能使用 SeleniumBasic。使用 SeleniumBasic 自动化 Edge 浏览器的详细步骤可以参考this thread

    【讨论】:

    • 到目前为止,我没有使用任何 Selenium 版本。我的意图是在不安装任何 Selenium 的情况下用 VBA 编写代码。现在,我清楚地明白,如果没有 SeleniumBasic 包,我无法将代码写入 Automate Edge Browser .
    猜你喜欢
    • 2022-07-06
    • 1970-01-01
    • 2020-10-30
    • 2020-05-03
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多