来自CME集团的VBA网络抓取

时间:2016-05-12 08:08:22

标签: html excel vba excel-vba web-scraping

我正在尝试从此网站上的API导入原油数据:Crude Oil 1 Options Quotes

我想获得Options打击范围的All数据。

当我尝试通过点击Excel中数据标签中的From Web来获取它时,该网站仅显示At the Money警示范围。

我想获得:类型:美国期权,到期时间:2016年6月,罢工范围:全部

如何使用VBA将原油数据导入Excel电子表格?

2 个答案:

答案 0 :(得分:1)

提琴手和网络流量:

在此页面上,我使用fiddler检查了网络流量。我看到有一个GET请求来获取感兴趣的数据。 N.B.我使用了页面上的默认信息。进行更改可能会导致POST请求,该请求将大体上采用相同的方法,但需要带有任何所需Header信息等的基于参数的POST请求。

提琴手输出:

GET request Header


JSON响应:

GET请求返回了一个包含所有JSON的{​​{1}}字符串。

JSON示例:

JSON预览:

JSON preview

因此,我使用CALLS/PUTS请求复制了这个GET请求,然后使用JSONConverter处理了返回的XMLHTTP字符串*。

  

*注意:下载JSON并添加到项目后,您必须通过JSONConverter.bas

添加对Microsoft Scripting Runtime的引用

VBE > Tools > References生成的对象是字典,由前导Set JSON = JsonConverter.ParseJson(sResponse)表示。


JSON对象处理:

我使用"{"处理来自JSONConverter对象的访问信息。

初始词典的键为JSON


正在查看网页:

下面显示了网页标题和第一数据行。

Weboage header & row 1

我正在"quoteDelayed","quoteDelay","tradeDate","optionContractQuotes","underlyingFutureContractQuotes","empty"结构中查找有关JSONCallsStrike Price的信息。此信息似乎在键Puts

必填信息:

因此,我们可以将"optionContractQuotes"重新分配给原始JSON的这一部分(我们可以直接跳转到这一点,但我认为这可能有助于解释),

JSON

词典集合:

快速检查 new Set JSON = JSON("optionContractQuotes") 结构会告诉我这将是词典的集合。 JSON告诉我我有一个收藏夹,后面的"["跟以前一样,告诉我我有了字典,因为"{"在里面重复。

仔细检查后,我发现这些词典的键为"{"


我们真正关心的信息:

我们关心键"strikePrice","strikeRank","put","call","underlyingFutureContract""strikePrice""put""call"键具有原始字符串值,例如

"strikePrice"

"strikePrice": "140.0", "put"键具有关联的字典。还记得"call"吗?

呼叫字典对象的示例键:

从上面我们可以看到,字典"{""put"的键对应于原始源头,而值对应于我们在网页源表。

注意事项:网页标题和关联的"call"标题之间存在细微差别(JSON中还有更多信息...),因此映射的标题用于访问{{ 1}}结构,然后将其写出到工作表中的相应列:

JSON

为什么要打扰?

JSON结构的上述分析使我们到了现在知道的地方:

  1. 我们感兴趣的物品在哪里
  2. 这些项目将如何映射到我们的输出表(还记得有关标题和行数据的观点吗?)

写到工作表:

为了使事情变得容易,我将使用以下方法在工作表中对jsonHeaders = Array("updated", "highLowLimits", "volume", "high", "low", "priorSettle", "change", "last") JSON的标题进行硬编码:

"calls"

然后我可以使用以下命令一次性写出它们作为表头:

"puts"

我知道我的行是headers = Array("Updated", "Hi / Low Limit", "Volume", "High", "Low", "Prior Settle", "Change", "Last", "Strike Price", "Last", "Change", "Prior Settle", "Low", "High", "Volume", "Hi / Low Limit", "Updated") 。并且.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers 标头与"call", "Strike Price", "put"标头是相同的标头,但顺序相反:

这个方便的观察意味着,当我循环访问集合中的每个字典时,实际上是一行信息,可用于填充表;我可以将每个字典传递给助手子WriteToSheet。该帮助子使用所需的键来访问字典值并将其写入工作表。如果"put"的关联值可以直接写入表中间的第9列。否则,如果它是"call""strikePrice",我们可以循环"call"数组以访问所需的内部字典信息。请记住,"put"jsonHeaders本身就是字典,而"call"是原始字符串。

要保存两次循环标题,一次用于“ put”,一次用于“ call”,我将整个过程简写放入一个循环中:

"put"

然后,我们在表中放表格。


网页示例视图:

Sample


代码输出视图:

Code output


VBA:

"strikePrice"

答案 1 :(得分:0)

对于这样的事情,值经常变化,我认为你应该使用Power Query。原因是,PQ会更干净,更强大,你不必依赖复杂的VBA代码来获取你的数据,特别是当VBA对这些东西有点不稳定时,我相信你会放这背后有一些真正的钱,所以你想要完全依赖你得到的数据。

只需下载并安装PQ。

https://www.microsoft.com/en-us/download/confirmation.aspx?id=39379

将其指向您想要的网址并运行它。然后,将PQ放在计时器上,每1分钟左右刷新一次。数据>连接>属性。

enter image description here

我在本书中讨论了这个以及很多其他类似的技巧,你可以在这里找到。

https://www.amazon.com/Automating-Business-Processes-Reducing-Increasing-ebook/dp/B01DJJKVZC?ie=UTF8&keywords=ryan%20shuell&qid=1464012902&ref_=sr_1_1&sr=8-1