【问题标题】:URL Issue retrieving data quotes in Yahoo finance在雅虎财经中检索数据报价的 URL 问题
【发布时间】:2019-10-27 15:06:07
【问题描述】:

当我尝试从特定股票中检索报价时,来自 Yahoo 的 URL 不起作用。关于它有几个讨论,但是,关于 VBA 宏似乎没有显示任何内容

Sub Get_Data()
Dim URL As String
Dim Ticker As String
Dim http As New WinHttpRequest
Dim sCotes As String
Dim Lignes
Dim Valeurs
Dim i As Long
Dim j As Long
Dim sLigne As String
Dim sValeur As String

Ticker = Range("Ticker")

URL = "https://query1.finance.yahoo.com/v7/finance/download/TECK?period1=1540456339&period2=1571992339&interval=1d&events=history&crumb=kjOZLFv6ch2"
http.Send
sCotes = http.ResponseText

MsgBox sCotes

Lignes = Split(sCotes, Chr(10))
For i = 1 To UBound(Lignes) 'until the end of the Lignes variable
  sLigne = Lignes(i)
  Valeurs = Split(sLigne, ",")
  For j = 0 To UBound(Valeurs) - 1
  Select Case j
  Case 0
  sValeur = DateSerial(CLng(Left(Valeurs(0), 4)), CLng(Mid(Valeurs(0), 6, 2)), CLng(Right(Valeurs(0), 2)))
  Case 5
  sValeur = CLng(Valeurs(5))
  Case Else
  sValeur = CDbl(Replace(Valeurs(j), ".", ","))
  End Select
  Range("A1").Offset(i, j) = sValeur
  Application.StatusBar = Format(Cells(i, 1), "Short Date")
  Next
Next
Application.StatusBar = False

End Sub

Http.send 步骤执行错误:“在调用 Open 方法之前无法调用此方法”

【问题讨论】:

    标签: excel vba web-scraping get yahoo-finance


    【解决方案1】:

    在尝试发送之前,您需要使用“open”方法,GET 非常好。但是,有几件事......

    有一个更简单的方法。值得添加的标头是 User-Agent 和一个用于减轻服务缓存结果的标头。下面向您展示如何在指定时间段内从服务器获取 json 响应并写入 Excel。注意:您需要将代码连接到 url。您可能还应该测试来自服务器的响应代码以确保成功。

    我使用 jsonconverter.bas 作为 json 解析器来处理响应。从here 下载原始代码并添加到名为 JsonConverter 的标准模块中。然后您需要转到 VBE > 工具 > 参考 > 添加对 Microsoft Scripting Runtime 的引用。从复制的代码中删除顶部的 Attribute 行。

    startDateendDate 的值需要作为 unix 时间戳传递。 @TimWilliams 编写了一个不错的函数 toUnix,用于将 Date 转换为我使用的 Unix here。我添加了自己的函数来管理相反方向的转换。

    此方法避免使用任何基于会话的标识符,从而避免您遇到无效 cookie 碎屑的问题。


    VBA:

    Option Explicit
    
    Public Sub GetYahooHistoricData()
        Dim ticker As String, ws As Worksheet, url As String, s As String
        Dim startDate As Long, endDate As Long
    
        Set ws = ThisWorkbook.Worksheets("Sheet1")
        ticker = ws.Range("ticker")                  'Range A1. Above write out range
    
        endDate = toUnix("2019-10-27")
        startDate = toUnix("2018-10-25")
        url = "https://query1.finance.yahoo.com/v8/finance/chart/" & ticker & "?region=US&lang=en-US&includePrePost=false&interval=1d&period1=" & startDate & "&period2=" & endDate & "&corsDomain=finance.yahoo.com&.tsrc=finance"
    
        With CreateObject("MSXML2.XMLHTTP")
            .Open "GET", url, False
            .setRequestHeader "User-Agent", "Mozilla/5.0"
            .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
            .send
            s = .responseText
        End With
    
        Dim json As Object
    
        Set json = JsonConverter.ParseJson(s)("chart")("result")
    
        Dim dates As Object, results(), rows As Object, adjClose As Object, r As Long, headers()
    
        headers = Array("date", "close", "volume", "open", "high", "low", "adjclose")
        Set dates = json(1)("timestamp")
    
        ReDim results(1 To dates.Count, 1 To UBound(headers) + 1)
    
        Set rows = json(1)("indicators")("quote")(1)
        Set adjClose = json(1)("indicators")("adjclose")(1)("adjclose")
    
        For r = 1 To dates.Count
            results(r, 1) = GetDate(dates(r))
            results(r, 2) = rows("close")(r)
            results(r, 3) = rows("volume")(r)
            results(r, 4) = rows("open")(r)
            results(r, 5) = rows("high")(r)
            results(r, 6) = rows("low")(r)
            results(r, 7) = adjClose(r)
        Next
    
        With ws
            .Cells(3, 1).Resize(1, UBound(headers) + 1) = headers
            .Cells(4, 1).Resize(UBound(results, 1), UBound(results, 2)) = results
        End With
    End Sub
    
    Public Function GetDate(ByVal t As Variant) As String
        GetDate = Format$(t / 86400 + DateValue("1970-01-01"), "yyyy-mm-dd")
    End Function
    
    Public Function toUnix(ByVal dt As Variant) As Long
        toUnix = DateDiff("s", "1/1/1970", dt)
    End Function
    

    前 10 行示例:

    【讨论】:

    • 非常感谢大家的帮助!万分感激 !干杯
    【解决方案2】:

    尝试替换此代码

    URL = "https://query1.finance.yahoo.com/v7/finance/download/TECK?period1=1540456339&period2=1571992339&interval=1d&events=history&crumb=kjOZLFv6ch2"
    http.Send
    

    使用此代码:

    set http = Server.Createobject("MSXML2.ServerXMLHTTP.6.0")
    URL = "https://query1.finance.yahoo.com/v7/finance/download/TECK?period1=1540456339&period2=1571992339&interval=1d&events=history&crumb=kjOZLFv6ch2"
    http.open "POST", URL, False
    http.Send
    

    错误很明显:您需要在Send 方法之前调用open 方法。这也是一个 POST 请求。您可能还需要将这两行放在 open 方法之后:

    http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 
    http.setRequestHeader "Content-Length", 0
    

    【讨论】:

    • 你真的可以让代码使用“GET”吗?这是我收到的回复 - "finance": { "error": { "code": "Unauthorized", "description": "Invalid cookie"
    • 对我来说,它与 POST 配合得很好。它会发布数据 - period1=1540456339events=historycrumb=kjOZLFv6ch2 等。
    • @Vityata 你可能是对的,看了这个帖子之后:stackoverflow.com/questions/44030983/…。我已经编辑了我的答案。
    • 这很有趣,因为这与@Vityata 说他在使用 GET 请求而不是 POST 请求时收到的错误相同。所以现在看起来无论使用什么请求它都会返回相同的错误。在这种情况下,您的“kjOZLFv6ch2”cookie crumb 一定是无效的,因此请找出将您标识为 Yahoo! 的正确 cookie crumb。用户。
    【解决方案3】:

    这个问题大约 99% 与这里的问题重复 - How can I send an HTTP POST request to a server from Excel using VBA?。无论如何,错误很明显,因为.Send() 方法只是发送了一个完全空的Dim http As New WinHttpRequest 对象。

    要使代码正常工作,请从重复的问题中复制示例并打印http.ResponseText

    Sub TestMe()
    
        Dim http As Object
        Dim url As String
        Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
        url = "https://query1.finance.yahoo.com/v7/finance/download/TECK?period1=1540456339&period2=1571992339&interval=1d&events=history&crumb=kjOZLFv6ch2"
        http.Open "POST", url, False
        http.Send
        MsgBox http.responsetext
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多