Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.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
Excel VBA web源代码-如何将多个字段提取到一张工作表中_Vba_Excel_Web Scraping_Excel Web Query - Fatal编程技术网

Excel VBA web源代码-如何将多个字段提取到一张工作表中

Excel VBA web源代码-如何将多个字段提取到一张工作表中,vba,excel,web-scraping,excel-web-query,Vba,Excel,Web Scraping,Excel Web Query,大家下午好。在上一个查询的后续工作中,QHarr已经很好地解决了这个问题,我想对源代码中的多个字段而不是一个字段运行已解决的查询 我使用的URL是: 而采用“上一次收盘”价格的VBA代码为: Option Explicit Sub PreviousClose() Dim html As HTMLDocument, http As Object, ticker As Range Set html = New HTMLDocument Set

大家下午好。在上一个查询的后续工作中,QHarr已经很好地解决了这个问题,我想对源代码中的多个字段而不是一个字段运行已解决的查询

我使用的URL是:

而采用“上一次收盘”价格的VBA代码为:

Option Explicit

    Sub PreviousClose()
        Dim html As HTMLDocument, http As Object, ticker As Range
        Set html = New HTMLDocument
        Set http = CreateObject("WINHTTP.WinHTTPRequest.5.1")

    Dim lastRow As Long, myrng As Range
    With ThisWorkbook.Worksheets("Tickers")

        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        Set myrng = .Range("A2:A" & lastRow)

        For Each ticker In myrng
            If Not IsEmpty(ticker) Then
                With http
                    .Open "GET", "https://finance.yahoo.com/quote/" & ticker.Value & "?p=" & ticker.Value, False
                    .send
                    html.body.innerHTML = .responseText
                End With
                On Error Resume Next
                ticker.Offset(, 1) = html.querySelector("[data-test=PREV_CLOSE-value]").innertext

                On Error GoTo 0
            End If
        Next

    End With
End Sub
无论如何,理想情况下,每个字段都应该位于股票所用股票代码的右边

工作表截图:

非常感谢您的帮助。

谢谢。

tl;博士

下面的代码适用于给定的测试用例。关于更长的列表,请参见
ToDo
部分

API:

如果可能的话,您希望查看API以提供此信息。我相信现在提供的信息是雅虎财经API用来提供的*。有一个很好的JS教程。Alpha Vantage文档。在这个答案的最底部,我快速查看了通过API提供的时间序列函数

Web服务功能:

通过API键,您还可以潜在地使用Excel中的webservice函数来检索和解析数据。例如未测试。

XMLHTTPRequest和类:

但是,我将向您展示一种在URL上使用类和循环的方法。你可以改进这个。我使用一个名为
clsHTTP
的基本类来保存XMLHTTP请求对象。我给它两种方法。一个是
GetHTMLDoc
,用于返回html文档中的请求响应,另一个是
GetInfo
,用于从页面返回感兴趣的项目数组

以这种方式使用类意味着我们节省了重复创建和销毁xmlhttp对象的开销,并提供了一组很好的公开方法来处理所需的任务

假设您的数据如图所示,标题行为第2行

待办事项:

IMO,最明显的发展是您希望在中添加一些错误处理。例如,您可能希望开发类来处理服务器错误


VBA:

因此,在您的项目中添加一个名为
clsHTTP
的类模块,并放置以下内容:

clsHTTP

Option Explicit

Private http As Object
Private Sub Class_Initialize()
    Set http = CreateObject("MSXML2.XMLHTTP")
End Sub

Public Function GetHTMLDoc(ByVal URL As String) As HTMLDocument
    Dim html As HTMLDocument
    Set html = New HTMLDocument
    With http
        .Open "GET", URL, False
        .send
        html.body.innerHTML = StrConv(.responseBody, vbUnicode)
        Set GetHTMLDoc = html
    End With
End Function
Public Function GetInfo(ByVal html As HTMLDocument, ByVal endPoint As Long) As Variant
    Dim nodeList As Object, i As Long, result(), counter As Long
    Set nodeList = html.querySelectorAll("tbody td")
    ReDim result(0 To endPoint - 1)
    For i = 1 To 2 * endPoint Step 2
        result(counter) = nodeList.item(i).innerText
        counter = counter + 1
    Next    
    GetInfo = result
End Function
在标准模块中(模块1)

这将生成一个JSON响应,在整个返回字典的
时间序列(每日)
子字典中,返回了199个日期。每个日期都有以下信息:

对文档进行一点挖掘将揭示是否可以捆绑股票代码,我不能很快看到这一点,以及是否可以通过不同的查询字符串获得更多您感兴趣的初始项目

还有更多信息,例如,在URL调用中使用
TIME\u SERIES\u DAILY\u ADJUSTED
函数

https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=AA&outputsize=full&apikey=yourAPIkey
在这里,您将获得以下信息:

您可以使用JSON解析器(如)解析JSON响应,并且还有csv下载选项


*值得研究一下哪些API对您的项目覆盖率最高。Alpha Vantage似乎没有我上面的代码检索到的那么多;博士

下面的代码适用于给定的测试用例。关于更长的列表,请参见
ToDo
部分

API:

如果可能的话,您希望查看API以提供此信息。我相信现在提供的信息是雅虎财经API用来提供的*。有一个很好的JS教程。Alpha Vantage文档。在这个答案的最底部,我快速查看了通过API提供的时间序列函数

Web服务功能:

通过API键,您还可以潜在地使用Excel中的webservice函数来检索和解析数据。例如未测试。

XMLHTTPRequest和类:

但是,我将向您展示一种在URL上使用类和循环的方法。你可以改进这个。我使用一个名为
clsHTTP
的基本类来保存XMLHTTP请求对象。我给它两种方法。一个是
GetHTMLDoc
,用于返回html文档中的请求响应,另一个是
GetInfo
,用于从页面返回感兴趣的项目数组

以这种方式使用类意味着我们节省了重复创建和销毁xmlhttp对象的开销,并提供了一组很好的公开方法来处理所需的任务

假设您的数据如图所示,标题行为第2行

待办事项:

IMO,最明显的发展是您希望在中添加一些错误处理。例如,您可能希望开发类来处理服务器错误


VBA:

因此,在您的项目中添加一个名为
clsHTTP
的类模块,并放置以下内容:

clsHTTP

Option Explicit

Private http As Object
Private Sub Class_Initialize()
    Set http = CreateObject("MSXML2.XMLHTTP")
End Sub

Public Function GetHTMLDoc(ByVal URL As String) As HTMLDocument
    Dim html As HTMLDocument
    Set html = New HTMLDocument
    With http
        .Open "GET", URL, False
        .send
        html.body.innerHTML = StrConv(.responseBody, vbUnicode)
        Set GetHTMLDoc = html
    End With
End Function
Public Function GetInfo(ByVal html As HTMLDocument, ByVal endPoint As Long) As Variant
    Dim nodeList As Object, i As Long, result(), counter As Long
    Set nodeList = html.querySelectorAll("tbody td")
    ReDim result(0 To endPoint - 1)
    For i = 1 To 2 * endPoint Step 2
        result(counter) = nodeList.item(i).innerText
        counter = counter + 1
    Next    
    GetInfo = result
End Function
在标准模块中(模块1)

这将生成一个JSON响应,在整个返回字典的
时间序列(每日)
子字典中,返回了199个日期。每个日期都有以下信息:

对文档进行一点挖掘将揭示是否可以捆绑股票代码,我不能很快看到这一点,以及是否可以通过不同的查询字符串获得更多您感兴趣的初始项目

还有更多信息,例如,在URL调用中使用
TIME\u SERIES\u DAILY\u ADJUSTED
函数

https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=AA&outputsize=full&apikey=yourAPIkey
在这里,您将获得以下信息:

您可以使用JSON解析器(如)解析JSON响应,并且还有csv下载选项


*值得研究一下哪些API对您的项目覆盖率最高。Alpha Vantage似乎没有我上面的代码检索到的那么多内容。

这是一些巧妙的代码!!我非常喜欢它!!顺便说一下,你可能想考虑用R来做这种事情。看看
library(finreportr)

# print available functions in finreportr
ls('package:finreportr')

my.ticker <- 'SBUX'

# set final year
my.year <- 2017

# get income for FB
my.income <- GetIncome(my.ticker, my.year)

# print result
print(head(my.income))


# get unique fields
unique.fields <- unique(my.income$Metric)

# cut size of string
unique.fields <- substr(unique.fields,1, 60)

# print result
print(unique.fields)


# set col and date
my.col <- 'Earnings Per Share, Basic'

# print earnings per share
print(my.income[my.income$Metric == my.col, ])


library(tidyquant)

# set stock and dates
my.ticker <- 'AAPL'
first.date <- '2017-01-01'
last.date <-  Sys.Date()

# get data with tq_get
my.df <- tq_get(my.ticker,
                get = "stock.prices", 
                from = first.date, 
                to = last.date)

print(tail(my.df))


# get key financial rations of AAPL
df.key.ratios <- tq_get("AAPL",get = "key.ratios")

# print it
print(df.key.ratios)