Yahoo Finance URL not working
我已经用下面的网址从雅虎财经上获取历史数据有一段时间了,但从昨天起它就停止工作了。
https://ichart.finance.yahoo.com/table.csv?间谍=间谍
当浏览到此网站时,它会说:
Will be right back...
Thank you for your patience.
Our engineers are working quickly to resolve the issue.
号
然而,由于这个问题自昨天以来仍然存在,我开始认为他们停止了这项服务?
我的搜索结果只指向了这个主题,尽管它与https相关…
是否有其他人遇到此问题?我如何解决这个问题?他们是否提供对历史数据的不同访问?
它看起来像他们有增一开始所需的饼干,但你不可以访问这个fairly容易,例如:
1 | GET https://uk.finance.yahoo.com/quote/AAPL/history |
responds与头部的形状:
1 | set-cookie:B=xxxxxxxx&b=3&s=qf; expires=Fri, 18-May-2018 00:00:00 GMT; path=/; domain=.yahoo.com |
你应该能够读这两个附加的信息和你的
1 2 | GET https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=1492524105&period2=1495116105&interval=1d&events=history&crumb=tO1hNZoUQeQ cookie: B=xxxxxxxx&b=3&s=qf; |
注《
它看起来像你有一次
两个负载电流quotes说:
用:
- Apple取代用股份的股票
- 一个
[1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo] 区间 - 可选参数
period1 查询与你约会的时代范围开始如period1=1510340760 - 可选参数
period2 查询与你约会的时代,比如period2=1510663712 范围
雅虎已经进入了一个ReactJS前端,这意味着如果你分析从客户端到后端的请求头,你可以得到它们用来填充客户端存储的实际JSON。
主持人:query1.finance.yahoo.com http/1.0query2.finance.yahoo.com http/1.1(HTTP/1.0和HTTP/1.1之间的差异)
如果计划使用代理或持久连接,请使用
/v10/finance/quoteSummary/AAPL?modules= (以下模块完整列表)
(将符号替换为:aapl)
- 埃多克斯1〔5〕
示例URL:
- 埃多克斯1〔6〕
查询:
/v7/finance/options/AAPL (当前到期)/v7/finance/options/AAPL?date=1579219200 (2020年1月17日到期)
示例URL:
https://query2.yahoo.finance.com/v7/finance/options/AAPL (当前到期)https://query2.yahoo.finance.com/v7/finance/options/AAPL?date=1579219200 (2020年1月17日到期)
任何表示为unix时间戳的有效未来到期都可以在
- 埃多克斯1〔17〕
间隔:
&interval=3mo 3个月,追溯至初始交易日。&interval=1d 1天,回到初始交易日。&interval=5m 5分钟,可追溯到80(ish)天。&interval=1m 1分钟,往回4-5天。
每一个间歇跑多远有点让人困惑,似乎不一致。我的假设是,雅虎内部正在计入交易日,而我天真的做法没有考虑假期。虽然这是一个猜测,YMMV。
注意:如果您查询的EDOCX1(起始日期)对于您所选择的时间间隔来说太远,那么无论您要求什么时间间隔,雅虎都会返回
添加市场前和市场后数据
埃多克斯1〔26〕
增加股息和分割
埃多克斯1〔27〕
示例URL:
- 埃多克斯1〔28〕
上述请求将在1天内返回所有股票代码AAPL的价格数据,包括上市前和上市后数据以及股息和分割。
注:
在管理工作了一.net两级获得有效的令牌(和饼干屑)从雅虎财经
完整的API对图书馆在新的历史fetching从雅虎财经的数据,你可以访问yahoofinanceapi在GitHub
这里是两个类的饼干屑和抓斗
token.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | using System; using System.Diagnostics; using System.Net; using System.IO; using System.Text.RegularExpressions; namespace YahooFinanceAPI { /// <summary> /// Class for fetching token (cookie and crumb) from Yahoo Finance /// Copyright Dennis Lee /// 19 May 2017 /// /// </summary> public class Token { public static string Cookie { get; set; } public static string Crumb { get; set; } private static Regex regex_crumb; /// <summary> /// Refresh cookie and crumb value Yahoo Fianance /// </summary> /// <param name="symbol">Stock ticker symbol</param> /// <returns></returns> public static bool Refresh(string symbol ="SPY") { try { Token.Cookie =""; Token.Crumb =""; string url_scrape ="https://finance.yahoo.com/quote/{0}?p={0}"; //url_scrape ="https://finance.yahoo.com/quote/{0}/history" string url = string.Format(url_scrape, symbol); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); request.CookieContainer = new CookieContainer(); request.Method ="GET"; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { string cookie = response.GetResponseHeader("Set-Cookie").Split(';')[0]; string html =""; using (Stream stream = response.GetResponseStream()) { html = new StreamReader(stream).ReadToEnd(); } if (html.Length < 5000) return false; string crumb = getCrumb(html); html =""; if (crumb != null) { Token.Cookie = cookie; Token.Crumb = crumb; Debug.Print("Crumb: '{0}', Cookie: '{1}'", crumb, cookie); return true; } } } catch (Exception ex) { Debug.Print(ex.Message); } return false; } /// <summary> /// Get crumb value from HTML /// </summary> /// <param name="html">HTML code</param> /// <returns></returns> private static string getCrumb(string html) { string crumb = null; try { //initialize on first time use if (regex_crumb == null) regex_crumb = new Regex("CrumbStore":{"crumb":"(?<crumb>.+?)"}", RegexOptions.CultureInvariant | RegexOptions.Compiled, TimeSpan.FromSeconds(5)); MatchCollection matches = regex_crumb.Matches(html); if (matches.Count > 0) { crumb = matches[0].Groups["crumb"].Value; } else { Debug.Print("Regex no match"); } //prevent regex memory leak matches = null; } catch (Exception ex) { Debug.Print(ex.Message); } GC.Collect(); return crumb; } } } |
更新1 6月17 两个"ed0906学分 修改正则表达式模式的两个
在这个论坛:http:/ / / / forums.yahoo.net T5雅虎金融服务/冰雅虎财务API破碎的TD P / / / / 3 250503页
尼克松说:
Hi All - This feature was discontinued by the Finance team and they will not be reintroducing that functionality.
《Python有情人了,有更新的yahoofinance.py在tradingwithpython图书馆。
有个笔记本也以"基于城市ed0906 demonstrating技巧,如何把数据步进。看到它的在线
《历史数据的URL下载的东西现在是这样的:
http:/ / / query1.finance.yahoo.com V7 /金融/下载/间谍?1492449771 period1 = = &;Period2 1495041771 &;一维区间= &;历史事件= = &;9gaimfhz.wu屑
注意以上的URL不会工作对你或任何人。你会得到这样的东西:
1 2 3 4 5 6 7 8 | { "finance": { "error": { "code":"Unauthorized", "description":"Invalid cookie" } } } |
它表明,雅虎现在是一些预防使用散列的数据访问的人从你这样做。不同的URL与每个会议,那么它很可能,你不能这样做有一个固定的URL了。
你会需要做一些scrapping两把正确的"主页的URL,例如:
finance.yahoo.com http:/ / / / /历史quote间谍吗?P =间谍
完整工作的PHP示例,基于本文和相关来源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function readYahoo($symbol, $tsStart, $tsEnd) { preg_match('"CrumbStore":{"crumb":"(?<crumb>.+?)"}"', file_get_contents('https://uk.finance.yahoo.com/quote/' . $symbol), $crumb); // can contain \uXXXX chars if (!isset($crumb['crumb'])) return 'Crumb not found.'; $crumb = json_decode('"' . $crumb['crumb'] . '"'); // \uXXXX to UTF-8 foreach ($http_response_header as $header) { if (0 !== stripos($header, 'Set-Cookie: ')) continue; $cookie = substr($header, 14, strpos($header, ';') - 14); // after 'B=' } // cookie looks like"fkjfom9cj65jo&b=3&s=sg" if (!isset($cookie)) return 'Cookie not found.'; $fp = fopen('https://query1.finance.yahoo.com/v7/finance/download/' . $symbol . '?period1=' . $tsStart . '&period2=' . $tsEnd . '&interval=1d' . '&events=history&crumb=' . $crumb, 'rb', FALSE, stream_context_create(array('http' => array('method' => 'GET', 'header' => 'Cookie: B=' . $cookie)))); if (FALSE === $fp) return 'Can not open data.'; $buffer = ''; while (!feof($fp)) $buffer .= implode(',', fgetcsv($fp, 5000)) . PHP_EOL; fclose($fp); return $buffer; } |
。
用途:
1 | $csv = readYahoo('AAPL', mktime(0, 0, 0, 6, 2, 2017), mktime(0, 0, 0, 6, 3, 2017)); |
在我的船一样。有一个越来越慢。在下载链接在页面的静态工厂历史价格。我加了两口饼干的Firefox扩展,记录在雅虎把饼干。使用价值的屑从交互式会话,我能够检索值。这里的人一个Perl脚本,测试工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | use Time::Local; # create unix time variables for start and end date values: 1/1/2014 thru 12/31/2017 $p1= timelocal(0,0,0,1,0,114); $p2= timelocal(0,0,0,31,11,117); $symbol = 'AAPL'; # create variable for string to be executed as a system command # cookies.txt exported from firefox # crumb variable retrieved from yahoo download data link $task ="wget --load-cookies cookies.txt --no-check-certificate -T 30 -O $symbol.csv "https://query1.finance.yahoo.com/v7/finance/download/$symbol?period1=$p1&period2=$p2&interval=1d&events=history&crumb=7WhHVu5N4e3""; #show what we're executing print $task; # execute system command using backticks `$task`; #output is AAPL.csv |
它会把一段两个automate在做什么。hopefully雅虎将简化或提供一些指导信息,如果他们真的intend两个使用它的人。
适用于Java爱好者。
您可以通过这种方式从URLConnection访问您的cookie。
1 2 3 4 5 6 7 8 9 10 11 12 | // "https://finance.yahoo.com/quote/SPY"; URLConnection con = url.openConnection(); ... for (Map.Entry<String, List<String>> entry : con.getHeaderFields().entrySet()) { if (entry.getKey() == null || !entry.getKey().equals("Set-Cookie")) continue; for (String s : entry.getValue()) { // store your cookie ... } } |
。
现在您可以在雅虎网站中搜索crumb:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | String crumb = null; InputStream inStream = con.getInputStream(); InputStreamReader irdr = new InputStreamReader(inStream); BufferedReader rsv = new BufferedReader(irdr); Pattern crumbPattern = Pattern.compile(".*"CrumbStore":\\{"crumb":"([^"]+)"\\}.*"); String line = null; while (crumb == null && (line = rsv.readLine()) != null) { Matcher matcher = crumbPattern.matcher(line); if (matcher.matches()) crumb = matcher.group(1); } rsv.close(); |
最后,设置cookie
1 2 3 4 5 6 7 8 9 10 | String quoteUrl ="https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1493425217&period2=1496017217&interval=1d&events=history&crumb=" + crumb ... List<String> cookies = cookieStore.get(key); if (cookies != null) { for (String c: cookies) con.setRequestProperty("Cookie", c); } ... con.connect(); |
。
我发现另一个雅虎网站不需要cookie,但会生成jason输出:https://query1.finance.yahoo.com/v7/finance/chart/yhoo?范围=2Y&Interval=1D&Indicators=Quote&includeTimestamps=true
这里指出:https://www.stock-data-solutions.com/kb/how-to-load-historical-prices-from-yahoo-finance-to-excel.htm
结果表明,它们似乎支持"perod1"和"period2"(在Unix时间中)参数,可以使用这些参数来代替"interval"。
1 2 3 4 5 | String quoteSite ="https://query1.finance.yahoo.com/v7/finance/chart/" + symbolName +"?" +"period1=" + period1 +"&period2=" + period2 +"&interval=1d&indicators=quote&includeTimestamps=true"; |
号
下面为我解析Jason:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | JSONObject topObj = new JSONObject(inp); Object error = topObj.getJSONObject("chart").get("error"); if (!error.toString().equals("null")) { System.err.prinltn(error.toString()); return null; } JSONArray results = topObj.getJSONObject("chart").getJSONArray("result"); if (results == null || results.length() != 1) { return null; } JSONObject result = results.getJSONObject(0); JSONArray timestamps = result.getJSONArray("timestamp"); JSONObject indicators = result.getJSONObject("indicators"); JSONArray quotes = indicators.getJSONArray("quote"); if (quotes == null || quotes.length() != 1) { return null; } JSONObject quote = quotes.getJSONObject(0); JSONArray adjcloses = indicators.getJSONArray("adjclose"); if (adjcloses == null || adjcloses.length() != 1) { return null; } JSONArray adjclose = adjcloses.getJSONObject(0).getJSONArray("adjclose"); JSONArray open = quote.getJSONArray("open"); JSONArray close = quote.getJSONArray("close"); JSONArray high = quote.getJSONArray("high"); JSONArray low = quote.getJSONArray("low"); JSONArray volume = quote.getJSONArray("volume"); |
Python
我使用此代码获取cookie(从Fix Yahoo Finance复制):
1 2 3 4 5 6 7 8 9 10 11 | def get_yahoo_crumb_cookie(): """Get Yahoo crumb cookie value.""" res = requests.get('https://finance.yahoo.com/quote/SPY/history') yahoo_cookie = res.cookies['B'] yahoo_crumb = None pattern = re.compile('.*"CrumbStore":\{"crumb":"(?P<crumb>[^"]+)"\}') for line in res.text.splitlines(): m = pattern.match(line) if m is not None: yahoo_crumb = m.groupdict()['crumb'] return yahoo_cookie, yahoo_crumb |
。
然后此代码得到响应:
1 2 3 4 5 6 7 8 9 10 11 | cookie, crumb = get_yahoo_crumb_cookie() params = { 'symbol': stock.symbol, 'period1': 0, 'period2': int(time.time()), 'interval': '1d', 'crumb': crumb, } url_price = 'https://query1.finance.yahoo.com/v7/finance/download/{symbol}' response = requests.get(url_price, params=params, cookies={'B': cookie}) |
这看起来也不错http://blog.bradlucas.com/posts/2017-06-03-yahoo-finance-quote-download-python/
我是这项服务的作者
此处显示基本信息
每日价格
您需要熟悉RESTful服务。
https://quantprice.herokuapp.com/api/v1.1/scoop/day?Tickers=MSFT&Date=2017年6月9日
历史价格
您必须提供日期范围:
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=msft&begin=2012-02-19&end=2012-02-20
如果不提供开始或结束日期,则将使用最早或当前日期:
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=msft&begin=2012-02-19
多个自动售票机
您可以用逗号分隔断续器:
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=ibm,msft&begin=2012-02-19
费率限制
所有请求的速率限制为每小时10个请求。如果你想注册一个完全访问的API,请在Twitter上给我发送dm。您将收到一个要添加到URL的API密钥。
我们正在建立一个PayPal帐户付费订阅无利率。
可用的票据列表
https://github.com/robotomic/valueviz/blob/master/scoop_tickers.csv
我还致力于提供EDGAR的基础数据和公司数据。干杯。
VBA
下面是一些vba函数,它们下载和提取cookie/crumb对,并将它们返回到
包含项目应具有对添加的"Microsoft XML,V6.0"库的引用(其他版本可能也可以,但对代码进行了一些较小的更改)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | Sub Test() Dim X As Collection Set X = FindCookieAndCrumb() Debug.Print X!cookie Debug.Print X!crumb Debug.Print YahooRequest("AAPL", DateValue("31 Dec 2016"), DateValue("30 May 2017"), X) End Sub Function FindCookieAndCrumb() As Collection ' Tools - Reference : Microsoft XML, v6.0 Dim http As MSXML2.XMLHTTP60 Dim cookie As String Dim crumb As String Dim url As String Dim Pos1 As Long Dim X As String Set FindCookieAndCrumb = New Collection Set http = New MSXML2.ServerXMLHTTP60 url ="https://finance.yahoo.com/quote/MSFT/history" http.Open"GET", url, False ' http.setProxy 2,"https=127.0.0.1:8888","" ' http.setRequestHeader"Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" ' http.setRequestHeader"Accept-Encoding","gzip, deflate, sdch, br" ' http.setRequestHeader"Accept-Language","en-ZA,en-GB;q=0.8,en-US;q=0.6,en;q=0.4" http.setRequestHeader"User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" http.send X = http.responseText Pos1 = InStr(X,"CrumbStore") X = Mid(X, Pos1, 44) X = Mid(X, 23, 44) Pos1 = InStr(X,"""") X = Left(X, Pos1 - 1) FindCookieAndCrumb.Add X,"Crumb" '====================================== X = http.getResponseHeader("set-cookie") Pos1 = InStr(X,";") X = Left(X, Pos1 - 1) FindCookieAndCrumb.Add X,"Cookie" End Function Function YahooRequest(ShareCode As String, StartDate As Date, EndDate As Date, CookieAndCrumb As Collection) As String ' Tools - Reference : Microsoft XML, v6.0 Dim http As MSXML2.XMLHTTP60 Dim cookie As String Dim crumb As String Dim url As String Dim UnixStartDate As Long Dim UnixEndDate As Long Dim BaseDate As Date Set http = New MSXML2.ServerXMLHTTP60 cookie = CookieAndCrumb!cookie crumb = CookieAndCrumb!crumb BaseDate = DateValue("1 Jan 1970") If StartDate = 0 Then StartDate = BaseDate UnixStartDate = (StartDate - BaseDate) * 86400 UnixEndDate = (EndDate - BaseDate) * 86400 url ="https://query1.finance.yahoo.com/v7/finance/download/" & ShareCode &"?period1=" & UnixStartDate &"&period2=" & UnixEndDate &"&interval=1d&events=history&crumb=" & crumb http.Open"GET", url, False http.setRequestHeader"Cookie", cookie http.send YahooRequest = http.responseText End Function |
在使用一个PHP脚本使用fopen()的两个财务数据的存取,这是我snippets改性让它回去工作。
创建的日期和时间戳比开始日期:
1 2 | $timestampStart = mktime(0,0,0,$startMonth,$startDay,$startYear); $timestampEnd = mktime(0,0,0,$endMonth,$endDay,$endYear); |
空军fopen()所需的两个发送的Cookie和硬编码的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $cookie="YourCookieTakenFromYahoo"; $opts = array( 'http'=>array( 'method'=>"GET", 'header'=>"Accept-language: en " . "Cookie: B=".$cookie." " ) ); $context = stream_context_create($opts); |
使用fopen()把两个CSV文件:
1 2 3 4 | $ticker="TickerSymbol"; $crumb="CrumbValueThatMatchesYourCookieFromYahoo"; $handle = fopen("https://query1.finance.yahoo.com/v7/finance/download/".$ticker."?period1=".$timestampStart."&period2=".$timestampEnd."&interval=1d&events=history&crumb=".$crumb."","r", false, $context); |
现在你可以做你所做的所有的魔术在这之前随循环:
1 2 3 | while (!feof($handle) ) { $line_of_text = fgetcsv($handle, 5000); } |
确保你自己的价值观两个角度对
对于那些excel/vba用户,我使用上述建议开发了一种vba方法,从更新后的雅虎网站中提取历史价格。下面列出了关键代码片段,我还提供了我的测试工作簿。
首先请求获取crumb和cookie值,然后再尝试从雅虎中提取价格数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 | Dim strUrl As String: strUrl ="https://finance.yahoo.com/lookup?s=%7B0%7D" 'Symbol lookup used to set the values Dim objRequest As WinHTTP.WinHttpRequest Set objRequest = New WinHttp.WinHttpRequest With objRequest .Open"GET", strUrl, True .setRequestHeader"Content-Type","application/x-www-form-urlencoded; charset=UTF-8" .send .waitForResponse strCrumb = strExtractCrumb(.responseText) strCookie = Split(.getResponseHeader("Set-Cookie"),";")(0) End With |
请参阅以下雅虎历史价格提取链接到我的网站获取一个样本文件和更多关于我从雅虎网站提取历史安全价格的方法的详细信息。
我发现有一种方法很管用。请看我的帖子:
yahoo finance api/url不工作:python fix for pandas datareader,在这里我按照https://pypi.python.org/pypi/fix-yahoo-finance中的步骤安装fix-yahoo-finance-upgrade-no cache dir(并升级pandas-datareader以确保)并测试正常:
1 2 3 4 | from pandas_datareader import data as pdr import fix_yahoo_finance data = pdr.get_data_yahoo('BHP.AX', start='2017-04-23', end='2017-05-24') |
另外请注意,最后两个数据列的顺序是"adj close"和"volume",因此为了我的目的,我将这些列重置为原始顺序:
1 2 | cols = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close'] data = data.reindex(columns=cols) |
号
实际上,您不需要执行2个请求来获取雅虎数据。我使用这个链接https://ca.finance.yahoo.com/quote/aaap/history?周期1=1474000669&period2=1505536669&interval=1d&filter=history&frequency=1d
您可以从中获取cookie,但它以JSON格式为您包含了历史引用的数据。下载页面后,我会将JSON数据从中删除。保存URL请求。
javascript
找到饼干;
1 2 | match = document.cookie.match(new RegExp('B=([^;]+)')); alert (match[1]); |
。
找到面包屑;
1 2 | i=document.body.innerHTML.search("CrumbStore") if (i>=0) alert (document.body.innerHTML.substr(i+22,11)) |
找到移动面包屑;
1 2 | i=document.body.innerHTML.search('USER={"crumb":'); if (i>=0) alert(document.body.innerHTML.substr(i+15,11)); |
。
最好是等待页面(如https://finance.yahoo.com/quote/goog)首先加载,您可以核对一下;
1 | document.readyState |
。
到目前为止,另一种方法(雅虎、谷歌和Intrinio)是免费从Alpha Vantage获取历史数据。他们的网络服务提供日内、日内、调整后的股价和50多个技术指标。他们甚至通过Deriscope直接交付到Excel(也是免费的)。(我是后者的作者。)
我在同一艘船上。我设法从雅虎下载了一些vb.net frankencode的csv文件,这些文件是我用google、sof和一些头皮屑制作的。
然而,我发现了Intrinio(查找它),注册了,我的免费帐户每天能收到500个历史数据API调用,比雅虎有更多的数据和更准确的数据。我重新编写了intrinio api的代码,我高兴得像个蛤蜊。
顺便说一句,我不工作,也和里奇诺没有任何关系,但是他们节省了我的时间…
如果你试图连接雅虎软件API和Java。只需添加以下依赖项。
1 2 3 4 5 | <dependency> <groupId>com.yahoofinance-api</groupId> YahooFinanceAPI</artifactId> <version>3.13.0</version> </dependency> |
可以从Google Finance API获取当前和历史数据。对我很好。
对于python 3,用户更改为
url='https://query1.finance.yahoo.com/v7/finance/download/aaap?期间1=1494605670&period2=1495815270&interval=1d&events=history&crumb=ij.ilcjlkrz'
从
url='https://chartapi.finance.yahoo.com/instrument/1.0/aaap/chartdata;type=quote;range=10d/csv/'
和
响应=请求.urlopen(url)到response=requests.get(url,cookies='b':cookie)响应中的数据.text
数据格式完全不同,但至少目前工作正常
我结合了上面处理crumb/cookie刷新的一些想法,特别是来自@dennis,并创建了一个可以这样调用的vb.net类:
1 2 3 | Dim f = Await YahooFinanceFactory.CreateAsync Dim items1 = Await f.GetHistoricalDataAsync("SPY", #1/1/2018#) Dim items2 = Await f.GetHistoricalDataAsync("^FTSE", #1/1/2018#) |
类本身在这里:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | Imports System.Net Imports System.Net.Http Imports System.Text.RegularExpressions Namespace YahooFinance Public Class YahooHistoryPrice Public Property [Date] As DateTime Public Property Open As Double Public Property High As Double Public Property Low As Double Public Property Close As Double Public Property Volume As Double Public Property AdjClose As Double End Class Public Class YahooFinanceFactory Public Property Cookie As String Public Property Crumb As String Public Property CrumbUrl As String ="https://finance.yahoo.com/quote/{0}?p={0}" Public Property DownloadUrl As String ="https://query1.finance.yahoo.com/v7/finance/download/{0}?period1={1}&period2={2}&interval=1d&events={3}&crumb={4}" Public Property Timeout As Integer = 5 Public Property NoRefreshRetries As Integer = 10 Public Property NoDownloadRetries As Integer = 10 Private Property Regex_crumb As Regex Public Shared Async Function CreateAsync(Optional noRefreshRetries As Integer = 10, Optional noDownloadRetries As Integer = 10, Optional timeout As Integer = 5, Optional crumbUrl As String ="https://finance.yahoo.com/quote/{0}?p={0}", Optional downloadUrl As String ="https://query1.finance.yahoo.com/v7/finance/download/{0}?period1={1}&period2={2}&interval=1d&events={3}&crumb={4}") As Task(Of YahooFinanceFactory) Return Await (New YahooFinanceFactory With { .NoRefreshRetries = noRefreshRetries, .NoDownloadRetries = noDownloadRetries, .Timeout = timeout, .CrumbUrl = crumbUrl, .DownloadUrl = downloadUrl }).RefreshAsync() End Function Public Async Function GetHistoricalDataAsync(symbol As String, dateFrom As Date) As Task(Of IEnumerable(Of YahooHistoryPrice)) Dim count As Integer = 0 If Not IsValid Then Throw New Exception("Invalid YahooFinanceFactory instance") End If Dim csvData = Await GetRawAsync(symbol, dateFrom, Now).ConfigureAwait(False) If csvData IsNot Nothing Then Return ParsePrice(csvData) End If Return Array.Empty(Of YahooHistoryPrice) End Function Public Async Function GetRawAsync(symbol As String, start As DateTime, [end] As DateTime) As Task(Of String) Dim count = 0 While count < NoDownloadRetries Try Dim cookies = New CookieContainer cookies.Add(New Cookie("B", If(Cookie.StartsWith("B="), Cookie.Substring(2), Cookie),"/",".yahoo.com")) Using handler = New HttpClientHandler With {.CookieContainer = cookies} Using client = New HttpClient(handler) With {.Timeout = TimeSpan.FromSeconds(Timeout)} Dim httpResponse = Await client.GetAsync(GetDownloadUrl(symbol, start)).ConfigureAwait(False) Return Await httpResponse.Content.ReadAsStringAsync End Using End Using Catch ex As Exception If count >= NoDownloadRetries - 1 Then Throw End If End Try count += 1 End While Throw New Exception("Retries exhausted") End Function Private Function ParsePrice(ByVal csvData As String) As IEnumerable(Of YahooHistoryPrice) Dim lst = New List(Of YahooHistoryPrice) Dim rows = csvData.Split(Convert.ToChar(10)) For i = 1 To rows.Length - 1 Dim row = rows(i) If String.IsNullOrEmpty(row) Then Continue For End If Dim cols = row.Split(","c) If cols(1) ="null" Then Continue For End If Dim itm = New YahooHistoryPrice With {.Date = DateTime.Parse(cols(0)), .Open = Convert.ToDouble(cols(1)), .High = Convert.ToDouble(cols(2)), .Low = Convert.ToDouble(cols(3)), .Close = Convert.ToDouble(cols(4)), .AdjClose = Convert.ToDouble(cols(5))} If cols(6) <>"null" Then itm.Volume = Convert.ToDouble(cols(6)) End If lst.Add(itm) Next Return lst End Function Public ReadOnly Property IsValid() As Boolean Get Return Not String.IsNullOrWhiteSpace(Cookie) And Not String.IsNullOrWhiteSpace(Crumb) End Get End Property Public Function GetDownloadUrl(symbol As String, dateFrom As Date, Optional eventType As String ="history") As String Return String.Format(DownloadUrl, symbol, Math.Round(DateTimeToUnixTimestamp(dateFrom), 0), Math.Round(DateTimeToUnixTimestamp(Now.AddDays(-1)), 0), eventType, Crumb) End Function Public Function GetCrumbUrl(symbol As String) As String Return String.Format(Me.CrumbUrl, symbol) End Function Public Function DateTimeToUnixTimestamp(dateTime As DateTime) As Double Return (dateTime.ToUniversalTime() - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds End Function Private Async Function RefreshAsync(Optional symbol As String ="SPY") As Task(Of YahooFinanceFactory) Dim count = 0 While count < NoRefreshRetries And Not IsValid Try Using client = New HttpClient With {.Timeout = TimeSpan.FromSeconds(Timeout)} Dim httpResponse = Await client.GetAsync(GetCrumbUrl(symbol)).ConfigureAwait(False) Me.Cookie = httpResponse.Headers.First(Function(f) f.Key ="Set-Cookie").Value.FirstOrDefault?.Split(";"c)(0) Dim html = Await httpResponse.Content.ReadAsStringAsync Me.Crumb = GetCrumb(html) If Crumb IsNot Nothing Then Return Me End If End Using Catch ex As Exception If count >= NoRefreshRetries - 1 Then Cookie ="" Crumb ="" Throw End If End Try count += 1 End While Cookie ="" Crumb ="" Throw New Exception("Could not refresh YahooFinanceFactory") End Function Private Function GetCrumb(html As String) As String Dim crumb As String = Nothing If Regex_crumb Is Nothing Then Regex_crumb = New Regex("CrumbStore"":{""crumb"":""(?<crumb>.+?)""}", RegexOptions.CultureInvariant Or RegexOptions.Compiled, TimeSpan.FromSeconds(5)) End If Dim matches As MatchCollection = Regex_crumb.Matches(html) If matches.Count > 0 Then crumb = matches(0).Groups("crumb").Value crumb = System.Text.RegularExpressions.Regex.Unescape(crumb) Else Throw New Exception("Regex no match") End If Return crumb End Function End Class End Namespace |
号