使用VBA从网站提取数据时面临的问题

时间:2019-11-29 18:07:44

标签: html excel vba web-scraping

我需要从以下网站https://www.mrci.com/ohlc/ohlc-all.php中提取伦敦可可12月20日和3月21日的收盘价 Screenshot for the website

我为此编写了以下代码,但它引发了错误,请提供帮助:

raster
  • 代码出现以下错误:
  

运行时错误-438   对象不支持属性或方法。

2 个答案:

答案 0 :(得分:2)

您的错误是因为您正在集合上调用文档/节点方法。

Set allRowOfData = appIE.document.getElementsByClassName("strat").getElementsByTagName("tbody")(183)

getElementsByClassName("strat")返回一个集合,您需要对其进行索引才能使用方法getElementsByTagName

例如

Set allRowOfData = appIE.document.getElementsByClassName("strat")(0).getElementsByTagName("tbody")(183)

摘要方法:

由于不同futures的数据排列在一系列长的表行(tr)节点中,因此需要由前导{{1 }}标头(trs),检查随后的同级future中右边的th,然后从该行中提取右边的列(trs)值。需要在下一个mmmyy块的开头或同级td的结尾处停止;以先到者为准。


tl; dr;

HTML对于快速识别正确的future并不理想;并且使用的索引越多,程序就越脆弱。以下内容确实有假设,但更为可靠。

我使用XMLHTTP request是因为不需要使用浏览器。您有一个将来感兴趣的变量,并且trs使用CSS类选择器将所有标头trs收集到ths中,并循环直到目标className被发现。这会将您置于感兴趣的第一行的开始。然后,各种nodeList在随后的行中。我通过使用辅助函数来检查表头并与定义的目标头名称进行比较来确定适当的列索引。该函数在找到标头的地方返回适当的索引,如果找不到则返回-1。

现在,我有一个字典,其中保存了future个感兴趣的时期。我循环所有mmmyy,直到找到下一部分(即标题为mmmyy的下一个tds)。我会连续检查每个tr,如果找到的th值在字典中,则会使用适当的列值更新字典。

在循环中,我的工作水平低于FirstChild,因此,为了利用FirstChild,我将当前的mmmyy转储到代理 HTMLDocument变量;然后,我可以再次访问querySelectorAll,并且可以通过索引选择适当的nextNode.NextSibling.OuterHTML。我需要将在HTMLDocument标记中传输的html包装起来,以使HTML解析器不抱怨并获得正确的#querySelectorAll元素。可以肯定的是,如果有时间重新审视此问题,我可以采取进一步措施。

最后,我将字典值写到表格上。


VBA:

td

阅读:

  1. css selectors
  2. document.querySelectorAll
  3. Node.nextSibling
  4. Node.parentNode

参考(VBE>工具>参考):

  1. Microsoft HTML对象库

答案 1 :(得分:1)

@QHarr's answer中所述,代码的问题是在集合上调用文档/模式方法。无论如何,遵循OP的方法,并尽可能使用其代码,这就是我创建的逻辑:

  • 打开URL并访问网站
  • 使用allRowsOfData = appIE.document.getElementsByClassName("strat")
  • 获取所有行
  • 开始遍历.Children的{​​{1}}
  • 通过allROwsOfData中的.Children(也称为“孙子”)开始内部循环:)
  • 对于每个“孙子”,看看是否是在innerText中带有“伦敦可可(LCE)”的那个。
  • 如果是,请制作.Children,然后在接下来的几行中找到found = TrueDec20的数据,并写下来。
  • 需要再次检查,以确保我们不会用下一个表Mar21覆盖数据。因此,如果If InStr(1, child2.outerhtml, "th class=") And Not CBool(InStr(1, child2.outerhtml, target))包含“ th class =“并且它不是child2.outerhtml中的那个,则London Cocoa(LCE)
  • 如果found = False为True,则开始用句号循环遍历字典,并检查第5列的值。这不是很灵活,就设计更改而言,这是错误的。
  • 最后,我们将字典中的内容写到Excel工作表中

代码:

found

奖金-整个代码,分为子和功能,位于我的网站-https://www.vitoshacademy.com/vba-extracting-financial-data-from-a-website-in-table-format/