Html 代码中的trs导致运行时错误

Html 代码中的trs导致运行时错误,html,excel,vba,parsing,web-scraping,Html,Excel,Vba,Parsing,Web Scraping,我正试图在我创建的文件夹中为一些公司提取现金流。我正在从市场观察中获取信息。我从中提取表格的网站的一个例子是。每个公司的所有股票代码符号都在A列中。我的代码在下一行出现错误“Runtime error”91 我知道HTML代码中有trs。另外,我为几家公司运行了代码)然后当我再次执行时,代码从未通过第一个(我第一次没有保存和关闭功能,因为我正在测试它,所以我退出了我做的每个工作簿,但我没有保存它们) 我使用上面的代码,然后使用下面的公共代码(出现问题的地方)来获取表 Public Sub Wri

我正试图在我创建的文件夹中为一些公司提取现金流。我正在从市场观察中获取信息。我从中提取表格的网站的一个例子是。每个公司的所有股票代码符号都在A列中。我的代码在下一行出现错误“Runtime error”91

我知道HTML代码中有trs。另外,我为几家公司运行了代码)然后当我再次执行时,代码从未通过第一个(我第一次没有保存和关闭功能,因为我正在测试它,所以我退出了我做的每个工作簿,但我没有保存它们)

我使用上面的代码,然后使用下面的公共代码(出现问题的地方)来获取表

Public Sub WriteTable(ByVal hTable As Object, Optional ByVal startRow As Long = 1, Optional ByVal ws As Worksheet)
If ws Is Nothing Then Set ws = ActiveSheet
Dim tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, c As Long
startRow = (M * 20) + 1
r = startRow
With ws
    Set tRow = hTable.getElementsByTagName("tr")
    For Each tr In tRow
        r = r + 1: c = 1
        Set tCell = tr.getElementsByTagName("td")
        For Each td In tCell
            .Cells(r, c).Value = td.innerText
            c = c + 1
        Next td
    Next tr
End With
End Sub

这不是一个理想的答案,但一定要检查你得到的回复。此外,还要检查hTable是否为空。如果我检查了回复,我会注意到该网站正在寻找机器人程序并使用验证码进行拦截

请原谅我们的打扰

当你浏览www.marketwatch.com时,你的浏览器让我们觉得你是一个机器人 可能发生的情况:

你是超级人类的超级用户,正在浏览这个网站 速度。您已在web浏览器中禁用JavaScript。第三方 Ghostery或NoScript等浏览器插件正在阻止JavaScript 此支持中提供了其他信息 文章

完成下面的验证码后,您将立即重新获得访问权限 请访问www.marketwatch.com

如果你确实是这样,你有几个选择:

1) 搜索其他信息来源

2) 使用浏览器自动化(selenium basic),并希望仅此一项,或通过适当的等待,就可以实现


3) 更改IP和用户代理。如果您最初能够在此页面上运行XHR,则可能是因为您现在已被网站添加到可疑机器人的监视列表中。交替使用IP和用户代理不是我愿意做的事情。

1)使用Option Explicit并声明所有变量。如果M是全局变量,请在其他情况下明确说明它需要传递给WriteTable函数。2)你检查过响应了吗?我能看到什么看起来像是验证码挡住了路。所以,HTTable最终什么都没有。@QHarr如果有验证码,我以前怎么能做过一次。只是好奇地想变得更有知识。如果有验证码,你以前从来没有做过一次r以前的活动可能会导致您现在成为可疑的机器人。在这种情况下,我的最后一个选项实际上可能是一种可能性,尽管您必须保持交替,希望这会起作用;这不是我个人会做的事情。@QHarr我可以通过vpn运行它吗?您可以尝试,但有很多方法可以将站点配置为识别机器人超越了IP和用户代理,特别是如果你在短时间内做了大量的请求。如果你尽可能地尝试,你将需要考虑其中的一些其他因素。
Public Sub Companies()
Dim sResponse As String, html As HTMLDocument, hTable As Object

Application.ScreenUpdating = False


Dim Last As Long
Dim i As Integer
Dim ws As Worksheet

Last = Cells(Rows.Count, "A").End(xlUp).Row
For i = Last To 572 Step -1

M = 0

Workbooks.Open "C:***\Desktop\Stock Portfolio\Stock Valuations\Temporary Valuations\" & Cells(i, "A").Value & ".xlsx"

ThisWorkbook.Activate
Set ws = Workbooks(Cells(i, "A").Value).Sheets.Add(After:= _
         Workbooks(Cells(i, "A").Value).Sheets(Workbooks(Cells(i, "A").Value).Sheets.Count))
ws.Name = "Cash Flow"

ThisWorkbook.Activate
Set html = New HTMLDocument
With CreateObject("MSXML2.XMLHTTP")
    .Open "GET", "https://www.marketwatch.com/investing/stock/" & Cells(i, "A").Value & "/financials/cash-flow", False
    .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
    .send
    sResponse = StrConv(.responseBody, vbUnicode)
End With

ThisWorkbook.Activate
With html
    .body.innerHTML = sResponse
    Set hTable = .getElementsByTagName("tbody")(0)
    WriteTable hTable, 1, Workbooks(Cells(i, "A").Value).Sheets("Cash Flow")
End With

ThisWorkbook.Activate

M = 3

With html
    .body.innerHTML = sResponse
    Set hTable = .getElementsByTagName("tbody")(1)
    WriteTable hTable, 1, Workbooks(Cells(i, "A").Value).Sheets("Cash Flow")
End With
Workbooks(Cells(i, "A")).Save
Workbooks(Cells(i, "A")).Close
Next
End Sub
Public Sub WriteTable(ByVal hTable As Object, Optional ByVal startRow As Long = 1, Optional ByVal ws As Worksheet)
If ws Is Nothing Then Set ws = ActiveSheet
Dim tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, c As Long
startRow = (M * 20) + 1
r = startRow
With ws
    Set tRow = hTable.getElementsByTagName("tr")
    For Each tr In tRow
        r = r + 1: c = 1
        Set tCell = tr.getElementsByTagName("td")
        For Each td In tCell
            .Cells(r, c).Value = td.innerText
            c = c + 1
        Next td
    Next tr
End With
End Sub