Vba I';我刮这个有困难
我正在试图理解为什么我的参考文献不能很好地收集这些数据 以下是网站示例:Vba I';我刮这个有困难,vba,excel,web-scraping,Vba,Excel,Web Scraping,我正在试图理解为什么我的参考文献不能很好地收集这些数据 以下是网站示例: 作为目标: <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
作为目标:
<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>
我知道上面的内容不会返回我想要的内容,因为注释会告诉您它提取到Excel中的内容。子元素似乎不像我构建的其他宏那样工作。我认为这样做会奏效:
Cells(1, 1) = Document.getElementById("Y_1").getAttribute("rawvalue")
但这不起作用,我也试过:
Cells(1, 1) = Document.getElementById("data_i6").getElementById("Y_1").innertext
这也不起作用。尝试将“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
下面将说明您遇到的一些问题
.querySelectorAll
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
您提到的确切元素是使用CSS选择器#Y_1
通过.document
方法返回的第二个索引。我的意思是身份证
从该网页返回以下内容(显示的示例-并非全部):
从上面可以看到,结果中的索引2返回了所需的字符串
查询选择Id为的调用?Id不是单个元素的唯一标识符吗?
此Id意外地不是页面上单个元素的唯一Id。它发生了27次:
这意味着您可以使用.querySelectorAll
方法返回所有匹配项的节点列表,并获取索引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
代码:(querySelector方法在querySelectorAll旁边注释掉)
选项显式
公共子系统获取信息()
Dim IE成为新的InternetExplorer
与IE
.Visible=True
.导航“http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=清除”
While.Busy=True或.readyState<4:DoEvents:Wend
将对象变暗,退出时间变为日期
exitTime=Now+时间序列(0,0,2)
做
多芬特
出错时继续下一步
设置a=.document.querySelector all(“#Y_1”)”.document.querySelector(“#data_i6#Y_1”)
错误转到0
如果现在>退出时间,则退出Do
循环,而a什么都不是
如果a为空,则退出Sub
调试.打印拆分(拆分(a.item(2).innerText,“rawvalue=”)(0),“>”)(0)拆分(拆分(a.innerText,“rawvalue=”)(0),“>”)(0)
调试.打印替换(拆分(拆分(a.item(2).outerHTML,“rawvalue=”)(1),“>”)(0),Chr$(34),vbNullString)替换(拆分(拆分(a.outerHTML,“rawvalue=”)(1),“>”)(0),Chr$(34),vbNullString)
退出
以
端接头
解决方案非常简单。只需使用它的属性“rawvalue”来调用它
这就是你可以做到的:
使用硬编码延迟
和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
此时的输出:
741131269
这对你有用吗
Sub web_table_option_two()
Dim HTMLDoc As New HTMLDocument
Dim objTable As Object
Dim lRow As Long
Dim lngTable As Long
Dim lngRow As Long
Dim lngCol As Long
Dim ActRw As Long
Dim objIE As InternetExplorer
Set objIE = New InternetExplorer
objIE.Navigate "http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=clear"
Do Until objIE.ReadyState = 4 And Not objIE.Busy
DoEvents
Loop
Application.Wait (Now + TimeValue("0:00:03")) 'wait for java script to load
HTMLDoc.body.innerHTML = objIE.Document.body.innerHTML
With HTMLDoc.body
Set objTable = .getElementsByTagName("table")
For lngTable = 0 To objTable.Length - 1
For lngRow = 0 To objTable(lngTable).Rows.Length - 1
For lngCol = 0 To objTable(lngTable).Rows(lngRow).Cells.Length - 1
ThisWorkbook.Sheets("Sheet1").Cells(ActRw + lngRow + 1, lngCol + 1) = objTable(lngTable).Rows(lngRow).Cells(lngCol).innerText
Next lngCol
Next lngRow
ActRw = ActRw + objTable(lngTable).Rows.Length + 1
Next lngTable
End With
objIE.Quit
End Sub
嗨,QHarr,终于在这个项目的工作结束后坐了下来。对非常感谢。这是一个完美的细分,我正在寻找的,我认为我这方面的主要问题是不知道“outerHTML”一词的用法,我试图指的是“rawvalue”,但它对我使用innertext或value键没有多大帮助。这就是我过去经常丢弃其他页面的原因。非常感谢你这么做。现在我得在我这边多做些工作来刮整张桌子!这会很有趣的!
741131269
Sub web_table_option_two()
Dim HTMLDoc As New HTMLDocument
Dim objTable As Object
Dim lRow As Long
Dim lngTable As Long
Dim lngRow As Long
Dim lngCol As Long
Dim ActRw As Long
Dim objIE As InternetExplorer
Set objIE = New InternetExplorer
objIE.Navigate "http://quote.morningstar.ca/Quicktakes/Financials/is.aspx?t=GNTX®ion=USA&culture=en-CA&ops=clear"
Do Until objIE.ReadyState = 4 And Not objIE.Busy
DoEvents
Loop
Application.Wait (Now + TimeValue("0:00:03")) 'wait for java script to load
HTMLDoc.body.innerHTML = objIE.Document.body.innerHTML
With HTMLDoc.body
Set objTable = .getElementsByTagName("table")
For lngTable = 0 To objTable.Length - 1
For lngRow = 0 To objTable(lngTable).Rows.Length - 1
For lngCol = 0 To objTable(lngTable).Rows(lngRow).Cells.Length - 1
ThisWorkbook.Sheets("Sheet1").Cells(ActRw + lngRow + 1, lngCol + 1) = objTable(lngTable).Rows(lngRow).Cells(lngCol).innerText
Next lngCol
Next lngRow
ActRw = ActRw + objTable(lngTable).Rows.Length + 1
Next lngTable
End With
objIE.Quit
End Sub