Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba I';我刮这个有困难_Vba_Excel_Web Scraping - Fatal编程技术网

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&region=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&region=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&region=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&region=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