使用VBA自动边缘浏览器,无需下载Selenium



我有Automation工具,这些工具是在考虑IE的情况下编写的。现在,我想通过考虑"Microsoft Edge";作为默认浏览器。除了下载作为Selenium包一部分的WebDriver之外,我找不到其他方法。

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

谢谢,Kanthi

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

方法1

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

Win升级+注册表修复

  1. 您的Windows版本至少需要20H2。您可以在此处查看您的Windows版本。

  2. 您的Windows需要在2022年3月之后进行最新的累积KB更新。您可以在此处查看您的Windows更新历史记录。

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

    Windows注册表编辑器5.00版

    [HHKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Main]"NotifyDisableIEOptions"=dword:000000002

    [HHKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode]"EnableGlobalWindowListInIEMode"=数据字:00000001

根据MS支持团队的说法,上述方法应有效到2029年。我相信,有关这方面的官方文件可能很快就会出台。

经过上述步骤后,VBA应能够与Edge IE模式交互,就像它是一个Internet Explorer窗口一样。您当前自动执行InternetExplorer.Application对象的代码也将使用Edge IE模式。

方法2

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

通过CDP使用VBA自动化Chrome/Edge-代码项目

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

有了这种方法,你现在甚至可以在不安装额外软件的情况下自动化Chrome。

我在这里创建了一个专门的Git,其中有一个演示文件:

https://github.com/longvh211/Chromium-Automation-with-CDP-for-VBA

方法3

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

示例代码1样本代码2

注意:以上代码适用于Office 32位。对于Office 64位,您需要转换它们(有关更多详细信息,请参阅此MSDN链接)

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

缺点是它适用于Edge IE模式。因此,仅在Edge而非IE模式下运行的web应用程序将无法使用此方法实现自动化。

你可以参考这个专用的Git,我在其中准备了一个演示文件:

https://github.com/longvh211/Edge-IE-Mode-Automation-with-IES-for-VBA

您可以考虑使用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 Not findEdgeDOM Is Nothing Then
    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
    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(0), 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)MicrosoftEdgeApplicationmsedge.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
    

您可以使用webdrivermanager包。以下是depedency:

对于Maven

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

对于渐变:

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

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

WebDriverManager.edgedriver().setup()

您正在使用哪个版本的Selenium?如果您使用的是Selenium3或Selenium4,可用的语言有Java、Python、C#、Ruby和JavaScript。您可以参考本文档了解更多信息。

如果要在VBA中使用Selenium自动执行Edge,则只能使用SeleniumBasic。有关使用SeleniumBasic自动执行Edge浏览器的详细步骤,您可以参考此线程。

最新更新