VBA 中有没有办法获取由 javascript 生成的元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11820548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way in VBA to get elements produced by javascript?
提问by adairdavid
I've been doing Google detective work for a few hours (including searching StackOverflow) for a technique to allow targeting of HTML elements produced by JavaScript in VBA.
我已经做了几个小时的谷歌侦探工作(包括搜索 StackOverflow),以寻求一种技术,以允许在 VBA 中定位由 JavaScript 生成的 HTML 元素。
As an example, I cannotuse ie.Document.getElementById(id) on this: http://www.kisfutures.com/electronic.html?page=quote&sym=NGU12&mode=i
例如,我不能在此使用 ie.Document.getElementById(id):http://www.kisfutures.com/electronic.html?page=quote&sym=NGU12&mode=i
However, that method is quite capable of finding elements on static pages, as tested on google.com.
但是,正如在 google.com 上测试的那样,该方法非常有能力在静态页面上查找元素。
I've played with simply getting all the InnerText from Document.body and then parsing the file for my desired TD values, but I ran into a roadblock when trying to split two values that are on different lines. As an illustration, the following was understood by Split(..) as "2040":
我只是简单地从 Document.body 获取所有 InnerText,然后解析文件以获得我想要的 TD 值,但是在尝试拆分不同行上的两个值时遇到了障碍。例如,Split(..) 将以下内容理解为“2040”:
20
40
From what I understand, the problem with getElementById(id) is that the website's table is generated by JavaScript after the page has loaded, and thus any elements created by that JavaScript cannot be targeted by my VBA code. Is there anyway to have my VBA code see this JavaScript-generated content?
据我了解,getElementById(id) 的问题在于网站的表格是在页面加载后由 JavaScript 生成的,因此我的 VBA 代码无法定位由该 JavaScript 创建的任何元素。有没有办法让我的 VBA 代码看到这个 JavaScript 生成的内容?
Thank you for your help!
感谢您的帮助!
Edit
编辑
The VBA code being used:
正在使用的 VBA 代码:
Function Quote(Market, Parameter)
Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate "http://www.kisfutures.com/electronic.html?page=quote&sym=NGU12&mode=i"
While ie.Busy
DoEvents
Wend
Dim id As String
id = "dt1_" & Market & "_" & StrConv(Parameter, vbLowerCase)
Quote = ie.Document.getElementByID(id).InnerText
ie.Quit
End Function
Basically I try to build an HTML element ID using the column header for the Market. So if, for example the market is "NGU12" and the column header is "Open", the ID built is: "dt1_NGU12_open", which is the ID for the TD element containing the "Open" value for market NGU12.
基本上,我尝试使用市场的列标题构建一个 HTML 元素 ID。因此,例如,如果市场是“NGU12”并且列标题是“Open”,则构建的 ID 是:“dt1_NGU12_open”,这是包含市场 NGU12 的“Open”值的 TD 元素的 ID。
回答by mkingston
As Tim has mentioned there should be no difference between statically and dynamically generated content when attempting access. Try this:
正如蒂姆所说,尝试访问时静态和动态生成的内容应该没有区别。尝试这个:
Function Quote(Market, Parameter)
Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate "http://www.kisfutures.com/electronic.html?page=quote&sym=NGU12&mode=i"
While ie.Busy
DoEvents
Wend
Application.Wait Now + TimeSerial(0,0,1) 'Pause 1 second, hopefully
'the dynamic content is
'generated within this
'time-frame
Dim id As String
id = "dt1_" & Market & "_" & StrConv(Parameter, vbLowerCase)
Quote = ie.Document.getElementByID(id).InnerText
ie.Quit
End Function
There are better ways of halting execution (see Windows Sleep API) but I'll leave that to you if you need more fine-grained control.
有更好的停止执行的方法(请参阅 Windows Sleep API),但如果您需要更细粒度的控制,我会将其留给您。
Also, if you'd like to test whether a specific id exists after the page has been generated you could load the page manually in IE and add a bookmarklet containing the following as the URL:
此外,如果您想在页面生成后测试特定 id 是否存在,您可以在 IE 中手动加载页面并添加包含以下内容的书签作为 URL:
javascript:void((function() {var a = document.getElementById(prompt('Please enter an id to test','dt1_NGU12_open')); if (a) {alert('Element found');} else {alert('Element not found')};})())