PHP code for Yahoo API for downloading CSV file

夙愿已清 提交于 2019-12-11 16:18:40

问题


I have been using the Yahoo Financial API to download historical stock data from Yahoo. As has been reported on this site, as of mid May, the old API was discontinued. There have been many posts addressed the the form of the new call, e.g.:

https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=315561600&period2=1496087439&interval=1d&events=history&crumb=XXXXXXXXXXX

As well as methods for obtaining the crumb:

Yahoo Finance URL not working

But I must be misunderstanding what the procedure is as I always get an error saying that it "Failed to open stream: HTTP request failed. HTTP/1.0 201 Unauthorized".

Below is my code. Any and all assistance is welcome. I have to admit that I am an old Fortran programmer and my coding reflects this.

Good Roads

Bill

$ticker = "AAPL";
$yahooURL="https://finance.yahoo.com/quote/" .$ticker ."/history";
$body=file_get_contents($yahooURL);
$headers=$http_response_header;
$icount = count($headers);
for($i = 0; $i < $icount; $i ++)
{
    $istart = -1;
    $istop = -1;
    $istart = strpos($headers[$i], "Set-Cookie: B=");
    $istop = strpos($headers[$i], "&b=");
    if($istart > -1 && $istop > -1)
    {
        $Cookie = substr ( $headers[$i] ,$istart+14,$istop - ($istart + 14));
    }
}

$istart = strpos($body,"CrumbStore") + 22;
$istop = strpos($body,'"', $istart);
$Crumb = substr ( $body ,$istart,$istop - $istart);

$iMonth = 1;
$iDay = 1;
$iYear = 1980;
$timestampStart = mktime(0,0,0,$iMonth,$iDay,$iYear);
$timestampEnd = time();

$url =  "https://query1.finance.yahoo.com/v7/finance/download/".$ticker."?period1=".$timestampStart."&period2=".$timestampEnd."&interval=1d&events=history&crumb=".$Cookie."";

while (!copy($url, $newfile) && $iLoop < 10)
{
    if($iLoop == 9) echo "Failed to download data." .$lf;
    $iLoop = $iLoop + 1;
    sleep(1);
}

回答1:


@Craig Cocca this isn't exactly a duplicate because the reference you gave gives a solution in python which for those of us who use php but haven't learnt python doesn't help much. I'd love to see as solution with php. I've examinied the yahoo page and am able to extract the crumb but can't work out how to put it into a stream and GET call. My latest (failed) effort is:

        $headers = [
        "Accept" => "*/*",
        "Connection" => "Keep-Alive",
        "User-Agent" => sprintf("curl/%s", curl_version()["version"])       
    ];

    // open connection to Yahoo
    $context = stream_context_create([
        "http" => [
            "header" => (implode(array_map(function($value, $key) { return sprintf("%s: %s\r\n", $key, $value); }, $headers, array_keys($headers))))."Cookie: $Cookie",
            "method" => "GET"
        ]
    ]);
    $handle = @fopen("https://query1.finance.yahoo.com/v7/finance/download/{$symbol}?period1={$date_now}&period2={$date_now}&interval=1d&events=history&crumb={$Crumb}", "r", false, $context);
    if ($handle === false)
    {
        // trigger (big, orange) error
        trigger_error("Could not connect to Yahoo!", E_USER_ERROR);
        exit;
    } 

    // download first line of CSV file
    $data = fgetcsv($handle);

The two dates are unix coded dates i.e.: $date_now = strtotime($date);




回答2:


I've now managed to download share price history. At the moment I'm only taking the current price figures but my download method receives historical data for the past year. (i.e. until Yahoo decides to put some other block on the data). My solution uses the "simple_html_dom.php" parser which I've added to my /includes folder. Here is the code (modified from the original version from the Harvard CS50 course which I recommend for beginners like me):

function lookup($symbol)
{
// reject symbols that start with ^
   if (preg_match("/^\^/", $symbol))
   {
       return false;
   }
// reject symbols that contain commas
   if (preg_match("/,/", $symbol))
   {
       return false;
   }
   // body of price history search
$sym = $symbol;
   $yahooURL='https://finance.yahoo.com/quote/'.$sym.'/history?p='.$sym;

// get stock name
$data = file_get_contents($yahooURL);
    $title = preg_match('/<title[^>]*>(.*?)<\/title>/ims', $data, $matches) ? $matches[1] : null;

$title = preg_replace('/[[a-zA-Z0-9\. \| ]* \| /','',$title);
$title = preg_replace('/ Stock \- Yahoo Finance/','',$title);
$name = $title;

// get price data - use simple_html_dom.php (added to /include)
$body=file_get_html($yahooURL);
$tables = $body->find('table');
$dom = new DOMDocument();
$elements[] = null;
$dom->loadHtml($tables[1]); 
$x = new DOMXpath($dom);
$i = 0;
foreach($x->query('//td') as $td){
        $elements[$i] = $td -> textContent." ";
    $i++;
}
$open = floatval($elements[1]); 
$high = floatval($elements[2]);
$low = floatval($elements[3]);
$close = floatval($elements[5]);
$vol = str_replace( ',', '', $elements[6]);
$vol = floatval($vol);
$date = date('Y-m-d');
$datestamp = strtotime($date);
$date = date('Y-m-d',$datestamp);
   // return stock as an associative array
   return [
        "symbol" => $symbol,
        "name" => $name,
        "price" => $close,
        "open" => $open,
        "high" => $high,
        "low" => $low,
        "vol" => $vol,
        "date" => $date
   ];
}


来源:https://stackoverflow.com/questions/44249819/php-code-for-yahoo-api-for-downloading-csv-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!