次のURLを使ってyahoo financeから過去のデータを取得していますが、昨日の時点では機能しなくなりました。
https://ichart.finance.yahoo.com/table.csv?s=SPY
このサイトを閲覧するときそれは言う:
戻ってきます...
お待ちいただいてありがとうございます。
私達のエンジニアは問題を解決するために迅速に取り組んでいます。
しかし、この問題は昨日からまだ存在しているので、私は彼らがこのサービスを中止したと考え始めていますか?
私のSO検索では、 このトピック のみが示されていましたが、これはhttpsに関連していましたが...
他に誰かがこの問題を経験していますか?どうすればこの問題を解決できますか?彼らは彼らの過去のデータへの異なるアクセスを提供していますか?
彼らは必要なクッキーを追加し始めているように見えますが、あなたはかなり簡単にこれを取得することができます、例えば:
GET https://uk.finance.yahoo.com/quote/AAPL/history
次の形式のヘッダーで応答します。
set-cookie:B=xxxxxxxx&b=3&s=qf; expires=Fri, 18-May-2018 00:00:00 GMT; path=/; domain=.yahoo.com
これを読んで.csv
リクエストに添付することができるはずです。
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;
crumb
クエリパラメータに注意してください。これは何らかの方法であなたのcookie
に対応するようです。あなたの最善の策は、あなたの最初のGETリクエストに対するHTMLレスポンスからこれをscrape
することです。その応答内で、"CrumbStore":\{"crumb":"(?<crumb>[^"]+)"\}
の正規表現検索を実行して、一致したグループを抽出することができます。
crumb
の値は、来年はどのシンボル/ティッカーでも同じcookie
と一緒に使用できますが、scrape
を頻繁に使用する必要はないように見えます。
現在の見積もりを取得するには、単にロードします。
https://query1.finance.yahoo.com/v8/finance/chart/AAPL?interval=2m
と:
[1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo]
の間隔1period1
クエリパラメータ。 period1=1510340760
period2
クエリパラメータ。 period2=1510663712
YahooはReactjsフロントエンドに行きました。つまり、クライアントからバックエンドまでのリクエストヘッダを分析すれば、クライアントサイドストアを埋めるためにそれらが使用する実際のJSONを取得できるということです。
query1.finance.yahoo.com
HTTP/1.0query2.finance.yahoo.com
HTTP/1.1( HTTP/1.0とHTTP/1.1の違い )プロキシまたは持続的な接続を使用する予定の場合はquery2.finance.yahoo.com
を使用してください。しかし、この記事の目的のために、URLの例に使用されているホストは、それが使用されているパスについて何かを暗示することを意味するものではありません。
/v10/finance/quoteSummary/AAPL?modules=
(以下のモジュールの全リスト)(AAPLをあなたのシンボルに置き換えてください)
?modules=
クエリの入力:
modules = [ 'assetProfile', 'incomeStatementHistory', 'incomeStatementHistoryQuarterly', 'balanceSheetHistory', 'balanceSheetHistoryQuarterly', 'cashflowStatementHistory', 'cashflowStatementHistoryQuarterly', 'defaultKeyStatistics', 'financialData', 'calendarEvents', 'secFilings', 'recommendationTrend', 'upgradeDowngradeHistory', 'institutionOwnership', 'fundOwnership', 'majorDirectHolders', 'majorHoldersBreakdown', 'insiderTransactions', 'insiderHolders', 'netSharePurchaseActivity', 'earnings', 'earningsHistory', 'earningsTrend', 'industryTrend', 'indexTrend', 'sectorTrend' ]
URLの例:
https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=assetProfile%2CearningsHistory
クエリ:assetProfile
とearningsHistory
%2C
は,
の16進数表現であり、要求する各モジュールの間に挿入する必要があります。 16進エンコーディングビットに関する詳細 (気にしているなら)
/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タイムスタンプとして表される有効な将来の有効期限は、?date=
クエリで使用できます。現在の有効期限を照会する場合、JSONレスポンスには?date=
クエリで使用できるすべての有効期限のリストが含まれます。 (これはPythonで人間が読める日付をUNIXのタイムスタンプに変換する方法を説明する記事です)
/v8/finance/chart/AAPL?symbol=AAPL&period1=0&period2=9999999999&interval=3mo
間隔:
&interval=3mo
3ヶ月、最初の取引日までさかのぼります。&interval=1d
1日、最初の取引日までさかのぼります。&interval=5m
5分、80(ish)日前に戻る。&interval=1m
1分、4〜5日前.それぞれの間隔でどれだけさかのぼって移動できるかはやや混乱し、矛盾しているようです。私の考えでは、ヤフーは内部的に取引日数を数えており、私の素朴なアプローチでは休日を考慮していませんでした。それは推測とYMMVですが。
period1=
:開始したい日付のunixタイムスタンプ表現。最初の取引日より下の値は最初の取引日に切り上げられます。
period2=
:終了したい日付のunixタイムスタンプ表現。最終取引日よりも大きい値は、利用可能な最新のタイムスタンプに切り捨てられます。
注:過去の選択した期間に対して長すぎるperiod1=
(開始日)で照会した場合、yahooあなたが要求した間隔に関係なく、3mo
間隔で価格を返します。] ==
前後の市場データを追加
&includePrePost=true
配当と分割を追加する
&events=div%2Csplit
URLの例:
https://query1.finance.yahoo.com/v8/finance/chart/AAPL?symbol=AAPL&period1=0&period2=9999999999&interval=1d&includePrePost=true&events=div%2Csplit
上記のリクエストは、前後の市場データならびに配当および分割を含む1日間隔でのティッカーAAPLのすべての価格データを返します。
注:period1=
およびperiod2=
の価格例のURLで使用されている値は、各入力の丸め動作を説明するためのものです。
私は、Yahoo Financeから有効なトークン(クッキーとパン粉)を取得するための.NETクラスを作成しました。
新しいYahoo Financeから履歴データを取得するための完全なAPIライブラリについては、Githubの YahooFinanceAPI をご覧ください。
これはクッキーとパン粉をつかむためのクラスです。
Token.cs
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;
}
}
}
6月1日更新
@ Ed0906のクレジット
パンくずの正規表現パターンをRegex("CrumbStore\":{\"crumb\":\"(?<crumb>.+?)\"}"
に変更
このフォーラムでは: https://forums.yahoo.net/t5/Yahoo-Finance-help/Is-Yahoo-Finance-API-broken/td-p/250503/page/
ニクソンは言った:
こんにちはすべて - この機能はFinanceチームによって廃止されました、そして、彼らはその機能性を再導入することはありません。
そこにいるPython愛好家のために、私はtradingWithPythonライブラリの yahooFinance.py を更新しました。
ステップごとにデータを取得する方法を示す、Ed0906によるヒントに基づいた例 ノートブック もあります。それを見て
履歴データをダウンロードするためのURLは次のようになりました。
上記のURLはあなたや他の人には機能しません。あなたはこのようなものを得るでしょう:
{
"finance": {
"error": {
"code": "Unauthorized",
"description": "Invalid cookie"
}
}
}
Yahooは現在、あなたがしたように他人がデータにアクセスするのを防ぐためにハッシュを使っているようです。 URLはセッションごとに異なるため、固定URLではこれができなくなる可能性が非常に高いです。
メインページから正しいURLを取得するには、いくつかのスクラップを実行する必要があります。次に例を示します。
この投稿と関連ソースに基づいて、十分に機能していますPHPの例
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;
}
使用法:
$csv = readYahoo('AAPL', mktime(0, 0, 0, 6, 2, 2017), mktime(0, 0, 0, 6, 3, 2017));
クッキーを必要としないが、jason出力を生成する別のyahooサイトを見つけました。 https://query1.finance.yahoo.com/v7/finance/chart/YHOO?range=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時間で)パラメータをサポートしているようです。
String quoteSite = "https://query1.finance.yahoo.com/v7/finance/chart/"
+ symbolName + "?"
+ "period1=" + period1
+ "&period2=" + period2
+ "&interval=1d&indicators=quote&includeTimestamps=true";
そして、以下はJasonを私のために解釈します。
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");
私は同じ船にいます。ゆっくりと着きます。過去の価格ページのダウンロードリンクはまだ機能します。それで、私はFirefoxにexport cookies拡張を追加し、yahooにログインし、cookieを捨てました。対話型セッションからの値を使用して、値を取得することができました。これはうまくいったテスト用のPerlスクリプトの一部です。
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
自動化するにはしばらく時間がかかります。彼らが本当にそれを使用することを意図しているならば、うまくいけば、yahooはそれを単純化するか、またはそれに関して何らかのガイダンスを与えるでしょう。
Java愛好家のために。
あなたはこのようにURLConnectionからあなたのクッキーにアクセスすることができます。
// "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
...
}
}
これで、Yahooのサイトでパン粉を検索できます。
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();
そして最後に、クッキーを設定する
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();
私はこのコードを使用してクッキーを取得しました( fix-yahoo-finance からコピーされたもの)。
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
それから応答を得るためにこのコード:
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/
私はこれの作者です service
基本情報 こちら
毎日の料金
RESTFULサービスに精通している必要があります。
https://quantprice.herokuapp.com/api/v1.1/scoop/day?tickers=MSFT&date=2017-06-09
過去の価格
日付範囲を入力する必要があります。
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=MSFT&begin=2012-02-19&end=2012-02-2
開始日または終了日を指定しないと、最も早い日付または現在の日付が使用されます。
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
レート制限
すべてのリクエストは1時間あたり10リクエストに制限されています。フルアクセスAPIに登録する場合は、TwitterでDMを送ってください。 URLに追加するためのAPIキーを受け取ります。
料金なしの有料購読用にPaypalアカウントを設定しています。
利用可能なティッカーのリスト
https://github.com/robomotic/valueviz/blob/master/scop_tickers.csv
私はまた、EDGARから基本データと会社データを提供するために働いています。乾杯。
財務データにアクセスするためにfopen()を使用してphpスクリプトを使用しました。これを機能させるために修正したスニペットは次のとおりです。
開始日と終了日のタイムスタンプを作成します。
$timestampStart = mktime(0,0,0,$startMonth,$startDay,$startYear);
$timestampEnd = mktime(0,0,0,$endMonth,$endDay,$endYear);
Fopen()に強制的にハードコードされた値で必要なクッキーを送信させます。
$cookie="YourCookieTakenFromYahoo";
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: B=".$cookie."\r\n"
)
);
$context = stream_context_create($opts);
Csvファイルを取得するにはfopen()を使用してください。
$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);
これで、whileループ内で前に行ったすべての魔法を実行できます。
while (!feof($handle) ) {
$line_of_text = fgetcsv($handle, 5000);
}
上記のスニペットの$ticker
、$crumb
および$cookie
には、必ず独自の値を設定してください。 $crumb
と$cookie
の取得方法については、 Ed0906のアプローチ に従ってください。
VBA
これは、cookie/crumbのペアをダウンロードして抽出し、それらをCollection
に返してから、これらを使用して特定のコードのcsvファイルの内容をダウンロードするVBA関数です。
含まれているプロジェクトは追加された 'Microsoft XML、v6.0'ライブラリへの参照を持つべきです(他のバージョンはコードへのいくつかのマイナーな変更でも大丈夫かもしれません)。
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
これらのExcel/VBAユーザーのために、私は更新されたYahooのウェブサイトから過去の価格を抽出するためのVBA方法を開発するために上記の提案を使いました。キーコードスニペットは以下のとおりです。また、テスト用ワークブックも提供しました。
価格からYahooからデータを抽出しようとする前に、まずCrumbとCookieの値を取得するよう要求します。
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 Webサイトから過去の保証価格を抽出するために使用した方法の詳細については、次の Yahoo Historical Price Extract Webサイトへのリンクを参照してください。
うまく動作することがわかったという修正があります。私の投稿を見てください。
Yahoo Finance API/URLが機能しない:Pandas DataReader のPython修正( https://の手順に従った) pypi.python.org/pypi/fix-yahoo-finance に:$ pip install fix_yahoo_finance --upgrade --no-cache-dir(および確実にアップグレードされたpandas_datareader)をインストールし、正常にテストされた:
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')
また、最後の2つのデータ列の順序は 'Adj Close'と 'Volume'です。したがって、私の目的のために、列を元の順序にリセットしました。
cols = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']
data = data.reindex(columns=cols)
クッキーを探す
match = document.cookie.match(new RegExp('B=([^;]+)'));
alert (match[1]);
パン粉を探します。
i=document.body.innerHTML.search("CrumbStore")
if (i>=0) alert (document.body.innerHTML.substr(i+22,11))
携帯用のパン粉を探します。
i=document.body.innerHTML.search('USER={\"crumb\":');
if (i>=0) alert(document.body.innerHTML.substr(i+15,11));
ページが最初に表示されるのを待つのがおそらく最善でしょう(例: https://finance.yahoo.com/quote/goog )、あなたはそれをチェックすることができます。
document.readyState
あなたは実際にYahooのデータを取得するために2つのリクエストをする必要はありません。このリンクを使用します https://ca.finance.yahoo.com/quote/AAAP/history?period1=1474000669&period2=1505536669&interval=1d&filter=history&frequency=1d
あなたはこれからクッキーをつかむことができますが、代わりにそれはJsonフォーマットであなたの過去の見積もりのためにそのデータを含みます。ページをダウンロードした後、Jsonのデータが不足しています。 URLリクエストを保存します。
これまでに述べたもの(Yahoo、Google、Intrinio)に代わるアプローチはAlpha Vantageから無料で過去のデータを入手することです。彼らのWebサービスは、日中、毎日、調整された株価と50以上のテクニカル指標を提供します。 Deriscopeを通じて、無料でもExcelに直接配信できます。 (私は後者の作者です。)
私は同じ船に乗っていた。私は、Google、SOF、およびいくつかの頭をひっくり返して作成したvb.netのフランケンコードを使用して、YahooからCSVをダウンロードすることができました。
しかし、私はIntrinioを発見し(サインアップ)、サインアップしました。そして私の無料アカウントで1日に500回の履歴データAPI呼び出しができました。 Intrinio API用にコードを書き直しました。
ところで、私は働いていないかIntrinioとは何の関係もありませんが、彼らは私のお尻の大きな時間を節約しました...
Python 3の場合は、
から
url = ' https://chartapi.finance.yahoo.com/instrument/1.0/AAAP/chartdata;type=quote;range=10d/csv/ '
そして
response.text内のresponse = requests.get(url、cookies = {'B':cookie})データに対するresponse = request.urlopen(url)
データフォーマットはまったく異なりますが、少なくとも今のところうまく機能しています
特に@Dennisからの、クラム/ Cookieの更新を処理する上記のアイデアをいくつか組み合わせて、次のように呼び出すことができるvb.netクラスを作成しました。
Dim f = Await YahooFinanceFactory.CreateAsync
Dim items1 = Await f.GetHistoricalDataAsync("SPY", #1/1/2018#)
Dim items2 = Await f.GetHistoricalDataAsync("^FTSE", #1/1/2018#)
クラス自体はここにあります:
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
google finance api から現在および過去のデータを取得することができます。私にとってはとてもうまくいきます。
あなたがJavaとyahooFinance APIを接続しようとしているなら。以下の依存関係を追加するだけです。
<dependency>
<groupId>com.yahoofinance-api</groupId>
<artifactId>YahooFinanceAPI</artifactId>
<version>3.13.0</version>
</dependency>