web-dev-qa-db-fra.com

L'URL de Yahoo Finance ne fonctionne pas

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?

50
jrn

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:

  • AAPL substitué avec votre ticker boursier
  • intervalle un de [1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo]
  • paramètre de requête period1 facultatif avec votre date de début d'étendue d'époque, par exemple. period1=1510340760
  • paramètre de requête period2 facultatif avec votre date de fin de plage d'époque, par exemple. period2=1510663712
36
Edd

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.

Hôtes:

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é.


Données fondamentales

  • /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)


Contrats d'options

  • /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)}


Prix

  • /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.

23
Ryder Brooks

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>.+?)\"}"

18
Dennis

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é. 

13
Ximix

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 

10
Jev

L'URL de téléchargement des données historiques ressemble maintenant à ceci:

https://query1.finance.yahoo.com/v7/finance/download/SPY?period1=1492449771&period2=1495041771&interval=1d&events=history&crumb=9GaimFhz.WU

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:

https://finance.yahoo.com/quote/SPY/history?p=SPY

10
whbogado

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));
5
Code4R7

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");
5
Serge

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.

5
George Statham

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();
5
Serge

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 .

3
user2471214

Python

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/

3
Lucas03

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
3
Govert

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.

2
jrn

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.

2
scott56hannah

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)
1
artDeco

Javascript

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
1
Humpity

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.

1
bandito40

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.)

1
Yannis

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 ...

1
Molasar

Pour Python 3, les utilisateurs passent à

uRL = ' https://query1.finance.yahoo.com/v7/finance/download/AAAP?period1=1494605670&period2=1495815270&interval=1d&events=history&crumb=IJ.ilcJlkrZ '

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 

0
user5473311

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
0
Liam

Il est possible d'obtenir des données actuelles et historiques de google finance api . Cela fonctionne très bien pour moi.

0
Super Mario

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>
0
Suneel