访问网页的框架文档,无需导航到此网页

标题可能会令人困惑,但这不仅仅是一个印象。 我有一个关于这个以前的post ,但核心问题实际上比这更深。

基本上,我有一个大的代码,我从我的公司导航到Intranet网页(让我们称之为开始网页)。

然后我提供用户名和密码信息,然后单击“login”button。 点击loginbutton将在新窗口中创build一个新的网页。 我们将这个新的网页称为网页。

主网页包含了我想获得的所有重要信息,而开始网页现在对我无用。

这里的第一个挑战是“启动”或“select”主页面,因为“开始”页面仍处于激活状态。 主网页显然有一个url,但不可能直接导航到这个url,所以我就说说网页的“激活”或“select”。 我设法在论坛的post的帮助下做到这一点

如果您有任何疑问,请告诉我,但这不是这篇文章的问题。

所以在主网页激活的情况下,我想单击一个元素来显示更多的信息。 这个元素embedded在框架postfachcontent中 。 请参阅主页上的HTML文档概述和缩放部分点击 。

在我之前提到的那篇文章中,我试图做到这一点,但是熟悉使embedded式任务变得更加困难的元素。

在其他成员的帮助下,我发现有两种方法可以进入后期内容框架:

  1. 通过孩子select孩子的框架:

    Set w = IEWindowFromLocation(path) Dim IEDoc As HTMLDocument Set IEDoc = w.document ' w is the so called Main webpage that I selected peviously in the code Dim SubFramesCollection As HTMLWindow2 Dim GoodFrame As HTMLWindow2 Dim Postfachcontent_Frame As HTMLWindow2 Set SubFramesCollection = IEDoc.frames ' the length of this is 3 since it contains the 3 main frames Set GoodFrame = SubFramesCollection(1).frames ' this contains the 2 frames of the "contentframe" frame so length = 2 Set Postfachcontent_Frame = GoodFrame(1) Doc2 = Postfachcontent_Frame.document 

但是,这里的问题是,一旦我访问框架,我很困惑如何真正select表中的元素,并点击它

  1. 通过“导航”到一个新的网页,这将是主要网页的简化版本,只关注我感兴趣的框架,以便导航到主网页URL&contentframe .src(或postfachcontent.src)。

但是,正如我上面所说,这里的问题是,我不能直接导航到主网页,所以我想我可以尝试声明一个新的InternetExplorer窗口,并给它一个位置,而不实际导航到页面(但它不'不幸的是工作)。 尝试如下:

  Set w = IEWindowFromLocation(path) Dim IEDoc As HTMLDocument Dim IEDok As HTMLDocument Set IEDoc = w.document Dim ContentFramesCollection As IHTMLElementCollection Dim ContentFrame As HTMLFrameElement Dim PostFachContentFramesCollection As IHTMLElementCollection Set ContentFramesCollection = IEDoc.getElementsByName("contentframe") ' this works and returns 1 item which is the frame called contentframe, so it sa collection of element containing 1 element only ' MsgBox ContentFramesCollection.Length ' returns 1 If Not ContentFramesCollection Is Nothing Then Set ContentFrame = ContentFramesCollection(0) ' Here we isolate the unique item contained in MainFramesCollection and store it in a single element called ContentFrame MsgBox w.document.Location & ContentFrame.src 'On Error Resume Next Set w2.document.Location = w.document.Location & ContentFrame.src 'MsgBox Err.Description ' returns automation error unspecified error Set IEDok = w2.document Set PostFachContentFramesCollection = IEDok.getElementsByName("postfachcontent") MsgBox PostFachContentFramesCollection.Length ' returns 0...oops End If 

感谢您的到达,欢迎任何帮助!

这里我的想法在代码(这个代码是未经测试的 )。 首先导航到开始页面登录。 然后找到主页面。 从主页面导航到第一帧,然后到第二帧。 之后,dom元素应该包含可以单击的目标按钮。 HTH

 Option Explicit ' Add reference to Microsoft Internet Controls (SHDocVw) ' Add reference to Microsoft HTML Object Library ' Add reference to Microsoft Shall Controls And Automation ' eg http://192.168.51.52:9999/SomeApp/Login Private Const StartUrl As String = "Your start URL" ' eg http://192.168.51.52:9999/SomeApp/Content Private Const MainUrl As String = "Your main URL" Sub ClickInsideOfFrame() Dim ie As SHDocVw.InternetExplorer Dim doc As MSHTML.HTMLDocument On Error GoTo error_handler ' Navigate to start page Set ie = New SHDocVw.InternetExplorer ie.Visible = True ie.navigate StartUrl WaitWhileBusy ie ' Enter user name and password and login Login ' Switch to Main page Set ie = IEWindowFromTitle(MainUrl) Set doc = ie.document ' First find content frame and navige to url of this frame NavigateToFrame ie, "frame[name='contentframe']" ' Find postfachcontent frame and navige to url of this frame next NavigateToFrame ie, "frame[name='postfachcontent']" ' Dom document should now contain the button which is inside of the ' postfachcontent frame doc.querySelector("input[type='button'][name='some-button']").Click error_handler: If Err.Number <> 0 Then MsgBox Err.Description, vbCritical, "Error" ie.Quit Set ie = Nothing End Sub Private Sub WaitWhileBusy(ie As SHDocVw.InternetExplorer) While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE DoEvents Wend End Sub Function IEWindowFromTitle(sTitle As String) As SHDocVw.InternetExplorer ' ... End Function Private Sub NavigateToFrame(ie As SHDocVw.InternetExplorer, selector As String) Dim frame As MSHTML.HTMLFrameElement Dim doc As MSHTML.HTMLDocument Set doc = ie.document Set frame = doc.querySelector(selector) If Not frame Is Nothing Then ie.navigate MainUrl & frame.src WaitWhileBusy ie Exit Sub End If Err.Raise vbObjectError + 513, "NavigateToFrame", "Frame not found for selector '" & selector & "'." End Sub Private Sub Login() ' ... End Sub 

解决方案:对于那些可能感兴趣的人,我在Dee的帮助下找到Tim Williams的帮助,在这里点击包含“onclick”属性的多个可能元素之一。

对于贪婪的人来说,这里是直接的单行解决方案 ,其中列出了可点击的元素:

 IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td") 

其中IEDoc是主网页的HTML文档。

备注:

  1. 为了得到这个最终的解决方案,我不得不做一些测试,看看我正在处理的类型,以确保我知道我在做什么。 您可以在下面的代码示例中看到这些测试步骤以及在注释中的MsgBox中显示的结果:

     MsgBox TypeName(IEDoc.getElementsByName("contentframe")(0)) ' returns HTMLFrameElement MsgBox IEDoc.getElementsByName("contentframe")(0).document.getElementsByName("postfachcontent").Length ' 0 MsgBox IEDoc.frames(1).frames.Length ' returns 2 MsgBox TypeName(IEDoc.frames(1).frames(1)) ' HTMLWindow2 MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable")) ' HTMLDivElement MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").getElementsByName("result")) ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")) 'DispElementcollection MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById ("notPrintable").document.getElementsByName("result")(0)) ' HTMLFormElement MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).getElementsByClassName("resultRow")) ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByClassName("resultRow")) ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document) ' HTMLDocument Result_Form_Doc = IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document ' error IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).Click ' works...but no click MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("tr")) ' DispHTMLElementCollection MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("tr").Length ' 12...weird...I counted 2 IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.querySelector("td[onclick='cView(62972172,'0', viewButton, '' );']").Click ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.querySelector("td[onclick='cView(62972172,'0', viewButton, '' );']")) 'error MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td").Length '42...counted 34 MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("table").Length ' 4...counted 1 IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td")(30).Click ' WORKSSSSS MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td").querySelectorAll("td[onclick='cView(62972172,'0', viewButton, '' );']").Length ' error MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td").querySelectorAll("td[rowSpan='1']").Length ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td")) ' DispHTMLElementCollection Dim Elem_td As IHTMLElement Dim el As Integer, ind As Integer Dim align_center_collection() el = 0 ind = 0 For Each Elem_td In IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td") el = el + 1 If Elem_td.Align = "center" Then ind = ind + 1 End If Next MsgBox el & " and " & ind ' if onclick : 42 and 0 (expected 34 and 16) ' if rowspan : 42 and 42(expected 34 and 34) ' if align = center : 42 and 2 (expected 34 and 2) - > good ' if align = left : 42 and 14 (expected 34 and 14) - > good ' if rowSpan : 42 and 42 (expected 34 and 34) 
    1. 我注意到,在某些时候,VBA的Intellisense不会再帮你了解可用的属性/方法,所以我必须经过一些测试
    2. 这似乎不可能以某种方式做这一步一步,因为即使typename返回一个有效的类型,我不能将其存储在一个相同类型的变量。
    3. 最后,我没有选择一个确切的元素,但是(因为你可以看到图片)有几个点击,我没有做“finition”。