Excel VBA:在 Mac 上获取 Yahoo Finance 数据
Excel VBA: get Yahoo Finance data on Mac
我正在尝试从 Mac 上的 Excel 上的 Yahoo Finance 获取数据。
据我所知,在 Mac 上获取网络数据的常用方法是 WebQuery。但是,有时它可以正常工作,有时会针对之前正常工作的同一组代码抛出错误 1004。错误文本:
"Microsoft Excel cannot access the file %link%. There are several possible reasons:"
我不知道为什么会这样。唯一的建议是因为 URL 不包含 Yahoo 需要的 cookie/crumb。
出于测试目的,我在 Windows 上使用了 WinHttpRequest
。它有效 - Excel 成功获取数据。
Mac 上有一个替代方案 - Tim Hall 的 WebHelpers。使用这套出色的工具,我能够在 Mac 上获得饼干和面包屑。
但是当我尝试从 Yahoo 下载 CSV 时,response.Content
有这个字符串:{"finance":{"result":null,"error":{"code":"Not Acceptable","description":"HTTP 406 Not Acceptable"}}}
.
一般来说,我有几个问题:
- 有没有办法将cookie添加到WebQuery方法中?不过,我不确定这是否有效并有助于避免错误。
- 为什么
Response
return 406错误?特别是这个代码片段:
client.BaseUrl = tickerURL
request.Method = HttpGet
request.Format = PlainText
request.AddCookie "Cookie", cookie
request.AddHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"
Set response = client.Execute(request)
resultFromYahoo = response.Content
这是使用 Windows 上的 WinHttpRequest
或 Mac 上 Tim Hall 的包接收 Yahoo Finance 数据的代码:
Sub getYahooFinanceData(stockTicker As String, StartDate As String, EndDate As String, frequency As String, cookie As String, crumb As String)
' forked from:
' http://investexcel.net/multiple-stock-quote-downloader-for-excel/
Dim resultFromYahoo As String
Dim objRequest
Dim csv_rows() As String
Dim tickerURL As String
'Make URL
tickerURL = "https://query1.finance.yahoo.com/v7/finance/download/" & stockTicker & _
"?period1=" & StartDate & _
"&period2=" & EndDate & _
"&interval=" & frequency & "&events=history" & "&crumb=" & crumb
'***************************************************
'Get data from Yahoo
#If Mac Then
Dim client As New WebClient
Dim response As WebResponse
Dim request As New WebRequest
client.BaseUrl = tickerURL
request.Method = HttpGet
request.Format = PlainText
request.AddCookie "Cookie", cookie
request.AddHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"
Set response = client.Execute(request)
DoEvents
'' ERROR 406 on MAC ''
If response.StatusCode = Ok Then
resultFromYahoo = response.Content
Else
MsgBox "An error occured while getting data for " & stockTicker & "'", vbInformation
Exit Sub
End If
#Else
Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
With objRequest
.Open "GET", tickerURL, False
.SetRequestHeader "Cookie", cookie
.Send
.WaitForResponse
resultFromYahoo = .ResponseText
End With
#End If
'***************************************************
csv_rows() = Split(resultFromYahoo, Chr(10))
End Sub
终于找到解决办法了!在与 Python 相关的类似主题中找到了答案:
总之,我们需要修改user-agent等请求参数来模拟真实的浏览器。而不是这一行:
request.AddHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"
我们需要添加 5 行:
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
request.AddHeader "Accept-Language", "en-US,en;q=0.5"
request.AddHeader "DNT", "1"
request.AddHeader "Connection", "close"
最后的子:
Sub getYahooFinanceData(stockTicker As String, StartDate As String, EndDate As String, frequency As String, cookie As String, crumb As String)
' forked from:
' http://investexcel.net/multiple-stock-quote-downloader-for-excel/
Dim resultFromYahoo As String
Dim objRequest
Dim csv_rows() As String
Dim tickerURL As String
'Make URL
tickerURL = "https://query1.finance.yahoo.com/v7/finance/download/" & stockTicker & _
"?period1=" & StartDate & _
"&period2=" & EndDate & _
"&interval=" & frequency & "&events=history" & "&crumb=" & crumb
'***************************************************
'Get data from Yahoo
#If Mac Then
Dim client As New WebClient
Dim response As WebResponse
Dim request As New WebRequest
client.BaseUrl = tickerURL
request.Method = HttpGet
request.Format = PlainText
request.AddCookie "Cookie", cookie
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
request.AddHeader "Accept-Language", "en-US,en;q=0.5"
request.AddHeader "DNT", "1"
request.AddHeader "Connection", "close"
Set response = client.Execute(request)
DoEvents
If response.StatusCode = Ok Then
resultFromYahoo = response.Content
Else
MsgBox "An error occured while getting data for '" & stockTicker & "'", vbInformation
Exit Sub
End If
#Else
Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
With objRequest
.Open "GET", tickerURL, False
.SetRequestHeader "Cookie", cookie
.Send
.WaitForResponse
resultFromYahoo = .ResponseText
End With
#End If
'***************************************************
csv_rows() = Split(resultFromYahoo, Chr(10))
End Sub
我正在尝试从 Mac 上的 Excel 上的 Yahoo Finance 获取数据。
据我所知,在 Mac 上获取网络数据的常用方法是 WebQuery。但是,有时它可以正常工作,有时会针对之前正常工作的同一组代码抛出错误 1004。错误文本:
"Microsoft Excel cannot access the file %link%. There are several possible reasons:"
我不知道为什么会这样。唯一的建议是因为 URL 不包含 Yahoo 需要的 cookie/crumb。
出于测试目的,我在 Windows 上使用了 WinHttpRequest
。它有效 - Excel 成功获取数据。
Mac 上有一个替代方案 - Tim Hall 的 WebHelpers。使用这套出色的工具,我能够在 Mac 上获得饼干和面包屑。
但是当我尝试从 Yahoo 下载 CSV 时,response.Content
有这个字符串:{"finance":{"result":null,"error":{"code":"Not Acceptable","description":"HTTP 406 Not Acceptable"}}}
.
一般来说,我有几个问题:
- 有没有办法将cookie添加到WebQuery方法中?不过,我不确定这是否有效并有助于避免错误。
- 为什么
Response
return 406错误?特别是这个代码片段:
client.BaseUrl = tickerURL
request.Method = HttpGet
request.Format = PlainText
request.AddCookie "Cookie", cookie
request.AddHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"
Set response = client.Execute(request)
resultFromYahoo = response.Content
这是使用 Windows 上的 WinHttpRequest
或 Mac 上 Tim Hall 的包接收 Yahoo Finance 数据的代码:
Sub getYahooFinanceData(stockTicker As String, StartDate As String, EndDate As String, frequency As String, cookie As String, crumb As String)
' forked from:
' http://investexcel.net/multiple-stock-quote-downloader-for-excel/
Dim resultFromYahoo As String
Dim objRequest
Dim csv_rows() As String
Dim tickerURL As String
'Make URL
tickerURL = "https://query1.finance.yahoo.com/v7/finance/download/" & stockTicker & _
"?period1=" & StartDate & _
"&period2=" & EndDate & _
"&interval=" & frequency & "&events=history" & "&crumb=" & crumb
'***************************************************
'Get data from Yahoo
#If Mac Then
Dim client As New WebClient
Dim response As WebResponse
Dim request As New WebRequest
client.BaseUrl = tickerURL
request.Method = HttpGet
request.Format = PlainText
request.AddCookie "Cookie", cookie
request.AddHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"
Set response = client.Execute(request)
DoEvents
'' ERROR 406 on MAC ''
If response.StatusCode = Ok Then
resultFromYahoo = response.Content
Else
MsgBox "An error occured while getting data for " & stockTicker & "'", vbInformation
Exit Sub
End If
#Else
Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
With objRequest
.Open "GET", tickerURL, False
.SetRequestHeader "Cookie", cookie
.Send
.WaitForResponse
resultFromYahoo = .ResponseText
End With
#End If
'***************************************************
csv_rows() = Split(resultFromYahoo, Chr(10))
End Sub
终于找到解决办法了!在与 Python 相关的类似主题中找到了答案:
总之,我们需要修改user-agent等请求参数来模拟真实的浏览器。而不是这一行:
request.AddHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"
我们需要添加 5 行:
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
request.AddHeader "Accept-Language", "en-US,en;q=0.5"
request.AddHeader "DNT", "1"
request.AddHeader "Connection", "close"
最后的子:
Sub getYahooFinanceData(stockTicker As String, StartDate As String, EndDate As String, frequency As String, cookie As String, crumb As String)
' forked from:
' http://investexcel.net/multiple-stock-quote-downloader-for-excel/
Dim resultFromYahoo As String
Dim objRequest
Dim csv_rows() As String
Dim tickerURL As String
'Make URL
tickerURL = "https://query1.finance.yahoo.com/v7/finance/download/" & stockTicker & _
"?period1=" & StartDate & _
"&period2=" & EndDate & _
"&interval=" & frequency & "&events=history" & "&crumb=" & crumb
'***************************************************
'Get data from Yahoo
#If Mac Then
Dim client As New WebClient
Dim response As WebResponse
Dim request As New WebRequest
client.BaseUrl = tickerURL
request.Method = HttpGet
request.Format = PlainText
request.AddCookie "Cookie", cookie
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
request.AddHeader "Accept-Language", "en-US,en;q=0.5"
request.AddHeader "DNT", "1"
request.AddHeader "Connection", "close"
Set response = client.Execute(request)
DoEvents
If response.StatusCode = Ok Then
resultFromYahoo = response.Content
Else
MsgBox "An error occured while getting data for '" & stockTicker & "'", vbInformation
Exit Sub
End If
#Else
Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
With objRequest
.Open "GET", tickerURL, False
.SetRequestHeader "Cookie", cookie
.Send
.WaitForResponse
resultFromYahoo = .ResponseText
End With
#End If
'***************************************************
csv_rows() = Split(resultFromYahoo, Chr(10))
End Sub