标题可能令人困惑,但它不仅仅是一种印象。 我有一个previous post,但核心问题实际上比这更深。
基本上我有一个很大的代码,我可以从我的公司导航到内部网页面(让我们将此网页称为开始网页)。
然后我提供用户名和密码信息,然后点击"登录"按钮。单击登录按钮将在新窗口中创建新网页。我们将此新网页称为主要网页。
主要网页包含我想要获取的所有重要信息,而“开始”网页现在对我来说毫无用处。
这里的第一个挑战是"激活"或"选择"自“开始”网页以来的主网页仍处于激活状态。主网页显然有一个URL,但直接导航到它是不可能的,这就是为什么我谈论"激活"或"选择"的网页。我设法在forum's post
的帮助下完成了这项工作如果您对此有任何疑问,请与我联系,但这不是此帖的问题。
因此,在激活主网页的情况下,我想点击一个元素来显示更多信息。此元素嵌入在框架 postfachcontent 中。 请参阅Main Page HTML document Overview和Zoom on part to click on。
在我上面提到的上一篇文章中,我试图这样做,但熟悉"嵌入式"使任务更难的元素。
在其他成员的帮助下,我发现有两种方法可以进入 postfachcontent 框架:
通过选择孩子的框架:
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
但问题是,一旦我访问了框架,我就如何实际选择表格元素并点击它感到困惑
但是,正如我上面所说,问题在于我无法直接导航到主网页,所以我想我可以尝试声明一个新的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 s a 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
感谢您的支持,欢迎任何帮助!
答案 0 :(得分:1)
这是我在代码中的想法(此代码是未经测试的)。首先导航到开始登录页面。然后找到主页面。从主页面导航到第一帧然后到第二帧。之后,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
' e.g. http://192.168.51.52:9999/SomeApp/Login
Private Const StartUrl As String = "Your start URL"
' e.g. 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
答案 1 :(得分:1)
解决方案:对于那些可能感兴趣的人,我在蒂姆·威廉姆斯的帮助下找到了here的一个方法来点击包含&#34; onclick&#34的多个可能元素之一;属性。
对于贪婪的人来说,这里是直接的一行解决方案,其中列出了可点击的元素:
IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td")
其中IEDoc是主网页的HTML文档。
备注:
为了获得最终解决方案,我必须做一些测试,看看我正在处理哪种类型,以确保我知道自己在做什么。您可以在以下代码示例中看到这些测试步骤,以及它们在注释中的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)