J'utilise l'URL suivante pour récupérer les données historiques de Yahoo Finance depuis un certain temps maintenant, mais cela a cessé de fonctionner depuis hier.
https://ichart.finance.yahoo.com/table.csv?s=SPY
Lors de la navigation sur ce site, il est indiqué:
Sera de retour ...
Merci pour votre patience.
Nos ingénieurs travaillent rapidement pour résoudre le problème.
Cependant, depuis que cette question existe toujours depuis hier, je commence à penser qu'ils ont cessé ce service?
Ma recherche SO m'a uniquement dirigée vers ce sujet , qui était lié à https bien que ...
Quelqu'un d'autre at-il rencontré ce problème? Comment puis-je résoudre ce problème? Offrent-ils un accès différent à leurs données historiques?
On dirait qu'ils ont commencé à ajouter un cookie obligatoire, mais vous pouvez le récupérer assez facilement, par exemple:
GET https://uk.finance.yahoo.com/quote/AAPL/history
Répond avec l'en-tête sous la forme:
set-cookie:B=xxxxxxxx&b=3&s=qf; expires=Fri, 18-May-2018 00:00:00 GMT; path=/; domain=.yahoo.com
Vous devriez pouvoir lire ceci et le joindre à votre requête .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;
Notez le paramètre de requête crumb
, cela semble correspondre à votre cookie
en quelque sorte. Votre meilleur pari est de scrape
ceci à partir de la réponse HTML à votre demande GET initiale. Dans cette réponse, vous pouvez effectuer une recherche regex sur: "CrumbStore":\{"crumb":"(?<crumb>[^"]+)"\}
et extraire le groupe de correspondances.
Il semble qu'une fois que vous ayez cette valeur crumb
, vous pouvez l'utiliser avec la même cookie
sur tout symbole/symbole pour l'année suivante, ce qui signifie que vous ne devriez pas avoir à faire la scrape
trop fréquemment.
Pour obtenir les devis actuels, il suffit de charger:
https://query1.finance.yahoo.com/v8/finance/chart/AAPL?interval=2m
Avec:
[1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo]
period1
facultatif avec votre date de début d'étendue d'époque, par exemple. period1=1510340760
period2
facultatif avec votre date de fin de plage d'époque, par exemple. period2=1510663712
Yahoo a opté pour une interface Reactjs, ce qui signifie que si vous analysez les en-têtes de requête du client vers le back-end, vous pouvez obtenir le code JSON qu’ils utilisent pour remplir les magasins côté client.
query1.finance.yahoo.com
HTTP/1.0query2.finance.yahoo.com
HTTP/1.1 ( différence entre HTTP/1.0 et HTTP/1.1 )Si vous prévoyez d'utiliser un proxy ou des connexions persistantes, utilisez query2.finance.yahoo.com
. Mais pour les besoins de cet article, l'hôte utilisé pour les exemples d'URL ne signifie en rien le chemin utilisé.
/v10/finance/quoteSummary/AAPL?modules=
(Liste complète des modules ci-dessous)(remplacez votre symbole par: AAPL)} _
Entrées pour la requête ?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' ]
Exemple d'URL:
https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=assetProfile%2CearningsHistory
Requête pour: assetProfile
et earningsHistory
Le %2C
est la représentation hexadécimale de ,
et doit être inséré entre chaque module demandé. détails sur le bit d'encodage hexadécimal (si vous y tenez)
/v7/finance/options/AAPL
(date d'expiration actuelle)/v7/finance/options/AAPL?date=1579219200
(expiration du 17 janvier 2020)Exemple d'URL:
https://query2.yahoo.finance.com/v7/finance/options/AAPL
(date d'expiration actuelle)https://query2.yahoo.finance.com/v7/finance/options/AAPL?date=1579219200
(expiration du 17 janvier 2020)Toute expiration future valide représentée par un horodatage UNIX peut être utilisée dans la requête ?date=
. Si vous interrogez sur l'expiration actuelle, la réponse JSON contiendra une liste de toutes les expirations valides pouvant être utilisées dans la requête ?date=
. (voici un article expliquant la conversion de dates lisibles par l'homme en horodatage Unix en Python)}
/v8/finance/chart/AAPL?symbol=AAPL&period1=0&period2=9999999999&interval=3mo
Intervalles:
&interval=3mo
3 mois, jusqu'à la date de négociation initiale.&interval=1d
1 jour, jusqu'à la date de négociation initiale.&interval=5m
5 minutes, remontant à 80 jours (ish).&interval=1m
1 minute, retour 4-5 jours.Jusqu'où vous pouvez aller avec chaque intervalle est un peu déroutant et semble incohérent. Mon hypothèse est que, à l’intérieur, yahoo compte en jours de bourse et que mon approche naïve ne tenait pas compte des jours fériés. Bien que ce soit une conjecture et YMMV.
period1=
: représentation timestamp unix de la date à laquelle vous souhaitez commencer à. Les valeurs inférieures à la date de négociation initiale seront arrondies à la date de négociation initiale.
period2=
: représentation timestamp unix de la date à laquelle vous souhaitez terminer. Les valeurs supérieures à la dernière date de négociation seront arrondies à l'horodatage le plus récent disponible.
Remarque: _ Si vous interrogez avec un period1=
(date de début) trop éloigné dans le passé pour l'intervalle que vous avez choisi, Yahoo renverra les prix dans l'intervalle 3mo
, quel que soit l'intervalle que vous avez demandé.
Ajouter des données pré et post marché
&includePrePost=true
Ajouter dividendes & fractionnements
&events=div%2Csplit
Exemple d'URL:
https://query1.finance.yahoo.com/v8/finance/chart/AAPL?symbol=AAPL&period1=0&period2=9999999999&interval=1d&includePrePost=true&events=div%2Csplit
La demande ci-dessus renverra toutes les données de prix du ticker AAPL 1 jour, y compris les données avant et après la mise sur le marché, ainsi que les dividendes et les scissions.
Remarque: _ les valeurs utilisées dans l'URL de l'exemple de prix pour period1=
et period2=
servent à illustrer le comportement d'arrondi respectif de chaque entrée.
J'ai réussi à mettre au point une classe .NET pour obtenir un jeton valide (cookie et sommaire) de Yahoo Finance.
Pour obtenir une bibliothèque complète d’API permettant de récupérer les données historiques à partir du nouveau compte Yahoo Finance, vous pouvez visiter YahooFinanceAPI dans Github
Voici la classe pour attraper le biscuit et la miette
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;
}
}
}
Mis à jour le 1 juin 17
.__ crédits à @ Ed0906
modifier le motif regex crumb en Regex("CrumbStore\":{\"crumb\":\"(?<crumb>.+?)\"}"
Dans ce forum: https://forums.yahoo.net/t5/Yahoo-Finance-help/Is-Yahoo-Finance-API-broken/td-p/250503/page/3
Nixon a dit:
Salut à tous - Cette fonctionnalité a été abandonnée par l'équipe des finances et elle ne réintroduira pas cette fonctionnalité.
Pour les amateurs de python, j'ai mis à jour la bibliothèque yahooFinance.py in tradingWithPython.
Il existe également un exemple notebook basé sur les astuces de Ed0906, montrant comment obtenir les données étape par étape. Le voir sur
L'URL de téléchargement des données historiques ressemble maintenant à ceci:
Notez que l'URL ci-dessus ne fonctionnera pas pour vous ou pour quelqu'un d'autre. Vous obtiendrez quelque chose comme ça:
{
"finance": {
"error": {
"code": "Unauthorized",
"description": "Invalid cookie"
}
}
}
Il semble que Yahoo utilise maintenant un hachage pour empêcher les gens d’accéder aux données comme vous l’avez fait. L'URL varie d'une session à l'autre. Il est donc très probable que vous ne puissiez plus le faire avec une URL fixe.
Vous aurez besoin de mettre au rebut pour obtenir l'URL correcte à partir de la page principale, par exemple:
Entièrement fonctionnel PHP exemple , basé sur ce post et les sources associées:
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;
}
Utilisation :
$csv = readYahoo('AAPL', mktime(0, 0, 0, 6, 2, 2017), mktime(0, 0, 0, 6, 3, 2017));
J'avais trouvé un autre site Yahoo ne nécessitant pas de cookies, mais générant une sortie jason: https://query1.finance.yahoo.com/v7/finance/chart/YHOO?range=2y&interval=1d&indicators=quote&includeTimestamps=true
il a été signalé à partir d'ici: https://www.stock-data-solutions.com/kb/how-to-load-historical-prices-from-yahoo-finance-to-Excel.htm
En fait, ils semblent prendre en charge les paramètres «perod1» et «period2» (en temps Unix) qui pourraient être utilisés à la place de «intervalle».
String quoteSite = "https://query1.finance.yahoo.com/v7/finance/chart/"
+ symbolName + "?"
+ "period1=" + period1
+ "&period2=" + period2
+ "&interval=1d&indicators=quote&includeTimestamps=true";
Et ce qui suit analyse Jason pour moi:
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");
Je suis dans le meme bateau. Y arriver lentement. Le lien de téléchargement sur la page des prix historiques fonctionne toujours. J'ai donc ajouté l'extension de cookies d'exportation à Firefox, connecté à Yahoo, jeté les cookies. Utilisé la valeur crumb de session interactive et j'ai été capable de récupérer des valeurs. Voici une partie d'un script de test Perl qui a fonctionné.
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
Cela va prendre un certain temps pour automatiser ce que je fais. Espérons que Yahoo simplifiera ou donnera quelques conseils à ce sujet s’ils ont vraiment l’intention de l’utiliser.
Pour les amoureux de Java.
Vous pouvez accéder à vos cookies à partir d'une connexion URLConnection de cette manière.
// "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
...
}
}
maintenant vous pouvez rechercher la miette sur le site 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();
et enfin, définir le cookie
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();
Je suis l'auteur de ce service
Informations de base ici
Prix du jour
Vous devez connaître les services RESTFUL.
https://quantprice.herokuapp.com/api/v1.1/scoop/day?tickers=MSFT&date=2017-06-09
Prix historiques
Vous devez fournir une plage de dates:
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=MSFT&begin=2012-02-19&end=2012-02-20
Si vous ne fournissez pas début ou fin, il utilisera la date la plus ancienne ou la plus récente:
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=MSFT&begin=2012-02-19
Plusieurs tickers
Vous pouvez simplement utiliser des tickers séparés par des virgules:
https://quantprice.herokuapp.com/api/v1.1/scoop/period?tickers=IBM,MSFT&begin=2012-02-19
Limite de débit
Toutes les demandes sont limitées à 10 demandes par heure. Si vous souhaitez vous inscrire à une API d'accès complet, envoyez-moi DM sur Twitter. Vous recevrez une clé API à ajouter à l'URL.
Nous mettons en place un compte Paypal pour un abonnement payant sans tarif.
Liste des tickers disponibles
https://github.com/robomotic/valueviz/blob/master/scoop_tickers.csv
Je travaille également à fournir des données fondamentales et des données sur la société à partir de EDGAR .
J'ai utilisé ce code pour récupérer un cookie (copié à partir de 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
alors ce code pour obtenir une réponse:
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})
Cela a l'air bien aussi http://blog.bradlucas.com/posts/2017-06-03-yahoo-finance-quote-download-python/
VBA
Voici quelques fonctions de VBA qui téléchargent et extraient la paire cookie/crumb et les renvoient dans une variable Collection
, puis les utilisent pour télécharger le contenu du fichier csv pour un code particulier.
Le projet contenant doit faire référence à la bibliothèque 'Microsoft XML, v6.0' ajoutée (une autre version pourrait également convenir moyennant quelques modifications mineures apportées au code).
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
J'ai utilisé un script php utilisant fopen () pour accéder aux données financières, voici les extraits que j'ai modifiés pour les remettre au travail:
Création des horodatages pour la date de début et la date de fin:
$timestampStart = mktime(0,0,0,$startMonth,$startDay,$startYear);
$timestampEnd = mktime(0,0,0,$endMonth,$endDay,$endYear);
Forcez fopen () à envoyer le cookie requis avec des valeurs codées en dur:
$cookie="YourCookieTakenFromYahoo";
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: B=".$cookie."\r\n"
)
);
$context = stream_context_create($opts);
Utilisez fopen () pour obtenir le fichier csv:
$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);
Maintenant, vous pouvez faire toute la magie que vous avez faite auparavant dans cette boucle while:
while (!feof($handle) ) {
$line_of_text = fgetcsv($handle, 5000);
}
Assurez-vous de définir vos propres valeurs pour $ticker
, $crumb
et $cookie
dans les extraits ci-dessus . Suivez L'approche de Ed0906 sur comment récupérer $crumb
et $cookie
.
Pour les utilisateurs d'Excel/VBA, j'ai utilisé les suggestions ci-dessus pour développer une méthode VBA permettant d'extraire les prix historiques du site Web mis à jour de Yahoo. Les extraits de code de clé sont répertoriés ci-dessous et j'ai également fourni mon cahier de test.
Commencez par demander à définir les valeurs Crumb et Cookie avant de tenter d'extraire les données de Yahoo pour les prix.
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
Voir le Yahoo Historique extrait de prix suivant mon lien vers mon site Web pour un exemple de fichier et plus de détails sur la méthode utilisée pour extraire les prix de sécurité historiques du site Web Yahoo.
J'ai trouvé un correctif qui fonctionne bien. S'il vous plaît voir mon post:
Yahoo Finance API/URL ne fonctionne pas: correctif Python pour Pandas DataReader où j'ai suivi les étapes de https://pypi.python.org/pypi/fix-yahoo-finance à: $ pip install fix_yahoo_finance --upgrade --no-cache-dir (et également mis à jour pandas_datareader pour en être sûr) et testé ok:
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')
Notez également que l'ordre des 2 dernières colonnes de données est "Fermé Adj" et "Volume", aussi, pour ma raison, j'ai réinitialisé les colonnes à l'ordre d'origine:
cols = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']
data = data.reindex(columns=cols)
Trouvez un cookie;
match = document.cookie.match(new RegExp('B=([^;]+)'));
alert (match[1]);
Trouvez des miettes.
i=document.body.innerHTML.search("CrumbStore")
if (i>=0) alert (document.body.innerHTML.substr(i+22,11))
Trouver des miettes pour mobile;
i=document.body.innerHTML.search('USER={\"crumb\":');
if (i>=0) alert(document.body.innerHTML.substr(i+15,11));
et il est probablement préférable d'attendre que la page (par exemple https://finance.yahoo.com/quote/goog ) soit chargée en premier, vous pouvez vérifier avec;
document.readyState
En fait, vous n'avez pas besoin de faire 2 demandes pour obtenir des données Yahoo. J'utilise ce lien https://ca.finance.yahoo.com/quote/AAAP/history?period1=1474000669&period2=1505536669&interval=1d&filter=history&frequency=1d
Vous pouvez récupérer le cookie à partir de ceci mais à la place, il inclut ces données pour votre citation historique au format Json. Après avoir téléchargé la page, j’écrase les données Json. Enregistre une demande d'URL.
Une approche alternative à celles mentionnées jusqu'à présent (Yahoo, Google et Intrinio) consiste à obtenir gratuitement les données historiques d'Alpha Vantage. Leur service Web fournit des cours boursiers ajustés quotidiens et quotidiens et plus de 50 indicateurs techniques en une journée. Ils livrent même directement à Excel - également gratuitement - via Deriscope. (Je suis l'auteur de ce dernier.)
J'étais sur le même bateau. J'ai réussi à télécharger le fichier CSV auprès de Yahoo avec du frankencode vb.net que j'ai fabriqué à partir de morceaux de Google, de SOF et de quelques casse-tête.
Cependant, j'ai découvert Intrinio (recherchez-le), je me suis inscrit et mon compte gratuit me permet de recevoir 500 appels d'api de données historiques par jour, avec beaucoup plus de données et beaucoup plus précises que Yahoo. J'ai réécrit mon code pour l'API Intrinio et je suis heureux comme une palourde.
BTW, je ne travaille pas ou n'ai rien à voir avec Intrinio, mais ils ont sauvé mon cul gros temps ...
Pour Python 3, les utilisateurs passent à
de
url = ' https://chartapi.finance.yahoo.com/instrument/1.0/AAAP/chartdata;type=quote;range=10d/csv/ '
et
response = request.urlopen (url) à response = requests.get (url, cookies = {'B': cookie}) données dans response.text
le format de données est totalement différent mais au moins son travail fonctionne bien pour l'instant
J'ai combiné certaines des idées ci-dessus qui traitent de l'actualisation de la chapelure/du cookie, en particulier de @Dennis, et j'ai créé une classe vb.net pouvant être appelée ainsi:
Dim f = Await YahooFinanceFactory.CreateAsync
Dim items1 = Await f.GetHistoricalDataAsync("SPY", #1/1/2018#)
Dim items2 = Await f.GetHistoricalDataAsync("^FTSE", #1/1/2018#)
La classe elle-même est ici:
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
Il est possible d'obtenir des données actuelles et historiques de google finance api . Cela fonctionne très bien pour moi.
Si vous essayez de connecter votre yahooFinance api à Java. ajoutez simplement la dépendance suivante.
<dependency>
<groupId>com.yahoofinance-api</groupId>
<artifactId>YahooFinanceAPI</artifactId>
<version>3.13.0</version>
</dependency>