我试图理解为什么我的参考资料不能很好地抓取这些数据。
这是网站的一个例子:
http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=clear
作为目标:
<div id="data_i6" class="rf_crow"><div id="Y_1" class="pos column6Width_noChart116px" style="overflow:hidden;white-space: nowrap;" rawvalue="741131269">741</div><div id="Y_2" class="pos column6Width_noChart116px" style="overflow:hidden;white-space: nowrap;" rawvalue="836611464">837</div><div id="Y_3" class="pos column6Width_noChart116px" style="overflow:hidden;white-space: nowrap;" rawvalue="939841654">940</div><div id="Y_4" class="pos column6Width_noChart116px" style="overflow:hidden;white-space: nowrap;" rawvalue="1010472512">1,010</div><div id="Y_5" class="pos column6Width_noChart116px" style="overflow:hidden;white-space: nowrap;" rawvalue="1100344312">1,100</div><div id="Y_6" class="pos column6Width_noChart116px" style="overflow:hidden;white-space: nowrap;" rawvalue="1115401551">1,115</div></div>
我需要提取的是rawvalue中的实际值=&#34; 741131269&#34;以下是我到目前为止所做的工作。
'Cells(1, 1) = Document.getElementsByClassName("rf_crow")'returns the rows of data into one cell
'Cells(1, 1) = Document.getElementById("Y_1").innerText 'returns the text for the year
'Cells(1, 1) = Document.getElementById("data_i1").innerText 'returns to first row of data
我知道上面的内容并没有返回我想要的内容,因为评论会告诉你它提取到Excel中的内容。子元素似乎不像我在其他构建的宏中那样工作。我觉得这样的事情会奏效:
Cells(1, 1) = Document.getElementById("Y_1").getAttribute("rawvalue")
但是,这也没有用,我试过了:
Cells(1, 1) = Document.getElementById("data_i6").getElementById("Y_1").innertext
那也不起作用。
答案 0 :(得分:1)
解决方案非常简单。只需使用它的'rawvalue。
属性来调用它您可以这样做:
使用Hardcoded delay
和for loop
检查所需值的可用性:
Sub GetValue()
Dim IE As New InternetExplorer, HTML As HTMLDocument, post As Object, elem As Object
With IE
.Visible = True
.Navigate "http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=clear"
While .Busy = True Or .ReadyState < 4: DoEvents: Wend
Set HTML = .Document
End With
''using hardcoded delay
Application.Wait Now + TimeValue("00:00:05")
For Each elem In HTML.getElementsByTagName("div")
If elem.innerText = "741" Then MsgBox elem.getAttribute("rawvalue"): Exit For
Next elem
End Sub
使用Explicit Wait
:
Sub GetValue()
Dim IE As New InternetExplorer, HTML As HTMLDocument, post As Object
With IE
.Visible = True
.Navigate "http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=clear"
While .Busy = True Or .ReadyState < 4: DoEvents: Wend
Set HTML = .Document
End With
Do: Set post = HTML.querySelector("#data_i6 #Y_1"): DoEvents: Loop While post Is Nothing
MsgBox post.getAttribute("rawvalue")
End Sub
此时输出:
741131269
答案 1 :(得分:0)
尝试将“objCollection”声明为对象,将strValue声明为字符串,并在下面的代码中,在第一行中替换您声明的http请求的名称:
Document.body.innerHTML = YourHTTPRequest.responseText
Set objCollection = Document.getElementsByClassName("rf_crow")
For Each objElement In objCollection
If objElement.ID = "Y_1" Then
strValue = objElement.getAttribute("rawvalue")
Exit For
End If
Next
Cells(1, 1) = strValue
答案 2 :(得分:0)
以下内容应说明您遇到的一些问题。
<强> .querySelectorAll 强>
您提到的确切元素是.document
使用CSS选择器#Y_1
的{{3}}方法返回的第二个索引。 .querySelectorAll
表示Id。
从该网页返回以下内容(显示的示例 - 并非全部):
从上面你可以看到你想要的字符串是由结果中的索引2返回的。
querySelectorAll with Id? Id不是单个元素的唯一标识符吗?
这个ID出乎意料地并不是页面上单个元素所独有的。它发生了27次:
这意味着您可以使用.querySelectorAll
方法返回所有匹配项的nodeList,并使用索引2处的项来获取结果。
注意:强>
如果您想要rawvalue
,741131269
旁边的长号,请解析返回元素的outerHTML
。
Debug.Print Replace(Split(Split(a.item(2).outerHTML, "rawvalue=")(1), ">")(0), Chr$(34), vbNullString)
<强> .querySelector 强>
或者,您可以使用
定位特定data_i6
的ID
.document.querySelector("#data_i6")
这个CSS选择器(#data_i6)返回每年的整行。如果使用.querySelector
,您将只获得第一个项目,即第1年。
您可以使用CSS选择器更具体,并添加额外的年份ID以获得感兴趣的年份:
#data_i6 #Y_1
代码:(在querySelectorAll旁边注释掉querySelector方法)
Option Explicit
Public Sub Get_Information()
Dim IE As New InternetExplorer
With IE
.Visible = True
.navigate "http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=clear"
While .Busy = True Or .readyState < 4: DoEvents: Wend
Dim a As Object, exitTime As Date
exitTime = Now + TimeSerial(0, 0, 2)
Do
DoEvents
On Error Resume Next
Set a = .document.querySelectorAll("#Y_1") ' .document.querySelector("#data_i6 #Y_1")
On Error GoTo 0
If Now > exitTime Then Exit Do
Loop While a Is Nothing
If a Is Nothing Then Exit Sub
Debug.Print Split(Split(a.item(2).innerText, "rawvalue=")(0), ">")(0) 'Split(Split(a.innerText, "rawvalue=")(0), ">")(0)
Debug.Print Replace(Split(Split(a.item(2).outerHTML, "rawvalue=")(1), ">")(0), Chr$(34), vbNullString) 'Replace(Split(Split(a.outerHTML, "rawvalue=")(1), ">")(0), Chr$(34), vbNullString)
.Quit
End With
End Sub
答案 3 :(得分:0)
这对您有用吗?
library(future.apply)