Yahoo Finance の株価情報をPHPで抽出してみた

November 6, 2013 – 9:02 pm

昨年(2012年) の8月から、Yahoo Finance で国内株価がリアルタイムで表示されるようになった。ここに表示されるデータを抽出してみることにした。抽出したデータを何にどのように使うかは決めてはいないが、プログラミングの練習くらいにはなるのでは、と思った次第。

データ抽出プログラムの仕様: 抽出の対象とするデータは、Yahoo Finance の株式欄のうち、(1)銘柄別ページに表示される株価関連データ、そして(2)日経平均や米ダウなどの国内外の株価インデックスのふたつとした。

それぞれのデータの簡単な仕様は以下のとおり:

  1. 銘柄別株価データ抽出用PHP関数: 銘柄コードを入力とし、Yahoo Financeの銘柄別株価情報のうち、「詳細情報」タグとして出力される全数値データ(参考指標、信用取引情報)を抽出するPHP関数を作成する。抽出した数値データは配列を戻り値とする。
  2. 株価インデックス関連情報抽出用PHP関数:国内外の株価インデックスを入力とし、Yahoo Finance の銘柄別株価情報として「詳細情報」として出力される数値データを抽出する。

なお、データの抽出方法は、以前このブログの「Webページの公開情報を自動的に抽出・取得する」で議論した方式を用いることにした。Webページからのデータ抽出方法として様々な方法が提案されているが、ここでは最も原始的な正規表現関数を用いた抽出法(パターンマッチングによる抽出)をとることにした。この方法、Yahoo Financeの仕様が変わると使えなくなってしまうという弱点はあるが、力まかせに誰でもできる方法といえる。

PHP関数とサンプルプログラム: 上述したPHP関数ふたつについて、PHPのソース、サンプルプログラム、動作(出力)例にをそれぞれ示す:

1. 銘柄別株価データ抽出用PHP関数

stock_value() PHPソース:

function stock_value($stock_code){
//************************************************************************************ 
//*    stock_value()  
//*-----------------------------------------------------------------------------------
//*        Argument : $stock_code
//*                       国内株式 銘柄コード 
//*        Return   : $ret_array
//*                       $ret_array[0]: チェックコード( =0: OK, !=0: NG ) 
//*                       $ret_array[1]: 主要情報
//*                       $ret_array[2]: 詳細情報
//*                       $ret_array[3]: 参考指標
//*                       $ret_array[4]: 信用取引情報
//************************************************************************************
    $url ="http://stocks.finance.yahoo.co.jp/stocks/detail/?code=" . $stock_code;
    $ch  = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $feed = curl_exec($ch);
    curl_close($ch);

    $n = preg_match_all("/class=\"yjSb real\"><span>([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt[0] = $cell[1][0];
    $n = preg_match_all("/class=\"symbol\"><h1>([^<]+)<\/h1>/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt[1] = $cell[1][0];
    $n = preg_match_all("/stoksPrice\"\>([^<]+)/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt[2] = $cell[1][0];
    $n = preg_match_all("/class=\"ico.* yjMSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt[3] = $cell[1][0];

    // --- 詳細情報 ---------//
    $n = preg_match_all("/<strong>([^<]+)<\/strong><span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $dtl[0][0]   = $cell[1][0];
    $dtl[0][1]   = $cell[2][0];
    $dtl[1][0]   = $cell[1][1];
    $dtl[1][1]   = $cell[2][1];
    $dtl[2][0]   = $cell[1][2];
    $dtl[2][1]   = $cell[2][2];
    $dtl[3][0]   = $cell[1][3];
    $dtl[3][1]   = $cell[2][3];
    $dtl[6][0]   = $cell[1][4];
    $dtl[6][1]   = $cell[2][4];
    $ref[3][0]   = $cell[1][5];
    $ref[3][1]   = $cell[2][5];
    $ref[6][0]   = $cell[1][6];
    $ref[6][1]   = $cell[2][6];
    $ref[7][0]   = $cell[1][7];
    $ref[7][1]   = $cell[2][7];
    $ref[8][0]   = $cell[1][8];
    $ref[8][1]   = $cell[2][8];
    $ref[10][0]  = $cell[1][9];
    $ref[10][1]  = $cell[2][9];
    $ref[11][0]  = $cell[1][10];
    $ref[11][1]  = $cell[2][10];

    $n = preg_match_all("/<strong>([^<]+)<\/strong>株<span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $dtl[4][0]   = $cell[1][0];
    $dtl[4][1]   = $cell[2][0];
    $ref[1][0]   = $cell[1][1];
    $ref[1][1]   = $cell[2][1];
    $trs[0][0]   = $cell[1][2];
    $trs[0][1]   = $cell[2][2];
    $trs[1][0]   = $cell[1][3];
    $trs[1][1]   = $cell[2][3];
    $trs[3][0]   = $cell[1][4];
    $trs[3][1]   = $cell[2][4];
    $trs[4][0]   = $cell[1][5];
    $trs[4][1]   = $cell[2][5];

    $n = preg_match_all("/<strong>([^<]+)<\/strong>千円<span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $dtl[5][0]  = $cell[1][0];
    $dtl[5][1]  = $cell[2][0];

    $n = preg_match_all("/<strong>([^<]+)<\/strong>百万円<span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $ref[0][0]  = $cell[1][0];
    $ref[0][1]  = $cell[2][0];

    $n = preg_match_all("/<strong>([^<]+)<\/strong>%<span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $ref[2][0]  = $cell[1][0];
    $ref[2][1]  = $cell[2][0];

    $n = preg_match_all("/<strong>([^<]+)<\/strong>倍<span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $ref[4][0] = $cell[1][0];
    $ref[4][1] = $cell[2][0];
    $ref[5][0] = $cell[1][1];
    $ref[5][1] = $cell[2][1];
    $trs[2][0] = $cell[1][2];
    $trs[2][1] = $cell[2][2];

    $n = preg_match_all("/<strong>([^<]+)<\/strong>株<\/dd>/", $feed, $cell, PREG_PATTERN_ORDER);
    $ref[9][0] = $cell[1][0];
    $ref[9][1] = "";

    $ret_array = array();

    $n_chk  =  sizeof( $prmdt ) * sizeof( $dtl ) * sizeof( $ref ) * sizeof( $trs );

    $ret_array[] =  $n_chk;
    $ret_array[] =  $prmdt; 
    $ret_array[] =  $dtl;
    $ret_array[] =  $ref;
    $ret_array[] =  $trs;

    $prmdt = NULL;
    $dtl   = NULL;
    $ref   = NULL;
    $trs   = NULL;

    return $ret_array;
}

サンプルプログラム command_stock.php:

<?php
require 'finance.php';

  $stock_code = "7203.T";

  $ret_array = stock_value($stock_code);
  $n_chk  = $ret_array[0];
  if ( $n_chk == 0 ) {
       echo "  Something Wrong! \n";
       echo "  Check stock_code \n";
       echo "  Stock_code =  " . $stock_code . " \n";
  }
  else {
        $prmdt  = $ret_array[1];
        $dtl    = $ret_array[2];
        $ref    = $ret_array[3];
        $trs    = $ret_array[4];

        echo $prmdt[1] . "\n";
        echo " 株価 at time of " . $prmdt[0] . " = " . $prmdt[2] . " 円\n";
        echo " 前日比          " . $prmdt[3] . "\n\n"; 

        echo "詳細情報 \n";
        echo "  前日終値          : " . $dtl[0][0] . $dtl[0][1] . "\n";
        echo "  始値              : " . $dtl[1][0] . $dtl[1][1] . "\n";
        echo "  高値              : " . $dtl[2][0] . $dtl[2][1] . "\n";
        echo "  安値              : " . $dtl[3][0] . $dtl[3][1] . "\n";
        echo "  出来高            : " . $dtl[4][0] . "株"   . $dtl[4][1] . "\n";
        echo "  売買代金          : " . $dtl[5][0] . "千円" . $dtl[5][1] . "\n";
        echo "  値幅制限          : " . $dtl[6][0] . $dtl[6][1] . "\n\n";

        echo "参考指標 \n";
        echo "  時価総額          : " . $ref[0][0] . "百万円" . $ref[0][1] . "\n";
        echo "  発行済株式数      : " . $ref[1][0] . "株" . $ref[1][1] . "\n"; 
        echo "  配当利回り(実績): " . $ref[2][0] . "%" . $ref[2][1] . "\n"; 
        echo "  1株配当(実績)   : " . $ref[3][0] . $ref[3][1] . "\n"; 
        echo "  PER(実績)       : " . $ref[4][0] . "倍" . $ref[4][1] . "\n"; 
        echo "  PBR(実績)       : " . $ref[5][0] . "倍" . $ref[5][1] . "\n"; 
        echo "  EPS(実績)       : " . $ref[6][0] . $ref[6][1] . "\n"; 
        echo "  BPS(実績)       : " . $ref[7][0] . $ref[7][1] . "\n"; 
        echo "  最低購入代金      : " . $ref[8][0] . $ref[8][1] . "\n"; 
        echo "  単元株数          : " . $ref[9][0] . "株" . $ref[9][1] . "\n"; 
        echo "  年初来高値        : " . $ref[10][0] . $ref[10][1] . "\n"; 
        echo "  年初来安値        : " . $ref[11][0] . $ref[11][1] . "\n\n"; 

        echo "信用取引情報 \n";

        echo "  信用買残          : " . $trs[0][0] . "株" . $trs[0][1] . "\n"; 
        echo "  前週比            : " . $trs[1][0] . "株" . $trs[1][1] . "\n"; 
        echo "  貸借倍率          : " . $trs[2][0] . "倍" . $trs[2][1] . "\n";
        echo "  信用売残          : " . $trs[3][0] . "株" . $trs[3][1] . "\n";
        echo "  前週比            : " . $trs[4][0] . "株" . $trs[4][1] . "\n"; 
   }
?>

出力例:

# php command_stock.php
トヨタ自動車(株)
 株価 at time of 15:00 = 6,350 円
 前日比          +30(+0.47%)

詳細情報 
  前日終値          : 6,320(11/05)
  始値              : 6,310(09:00)
  高値              : 6,400(13:28)
  安値              : 6,290(11:14)
  出来高            : 12,563,700株(15:00)
  売買代金          : 79,787,243千円(15:00)
  値幅制限          : 5,320~7,320(11/06)

参考指標 
  時価総額          : 21,894,784百万円(15:00)
  発行済株式数      : 3,447,997,492株(11/06)
  配当利回り(実績): 1.42%(15:00)
  1株配当(実績)   : 90.00(2013/03)
  PER(実績)       : (連) 20.90倍(15:00)
  PBR(実績)       : (連) 1.66倍(15:00)
  EPS(実績)       : (連) 303.82(2013/03)
  BPS(実績)       : (連) 3,835.30(2013/03)
  最低購入代金      : 635,000(15:00)
  単元株数          : 100株
  年初来高値        : 6,760(13/05/23)
  年初来安値        : 4,030(13/01/09)

信用取引情報 
  信用買残          : 11,568,400株(10/25)
  前週比            : +776,500株(10/25)
  貸借倍率          : 14.09倍(10/25)
  信用売残          : 820,800株(10/25)
  前週比            : -163,400株(10/25)

2. 株価インデックス関連情報抽出用PHP関数

index_value() PHPソース:

function index_value($index_code){
//*******************************************************************************************************
//*     index_value()
//*------------------------------------------------------------------------------------------------------
//*         Argument: $index_code
//*                      日経平均株価     : 998407.O         NYダウ            : ^DJI
//*                      TOPIX            : 998405.T         ナスダック総合    : ^IXIC
//*                      ジャスダック     : 23337.T          S&P500            : ^GSPC
//*                      香港ハンセン     : ^HSI             FTSE 100          : ^FTSE
//*                      上海総合         : 000001.SS        DAX               : ^GDAXI
//*                      ムンバイSENSEX30 : ^BSESN           CAC 40            : ^FCHI
//*         Return  : $ret_array
//*                     チェックコード ($n  =6: 国内インデックス  =7: 海外インデックス !=6,7 NG )
//*                     主要情報
//*                     詳細情報 
//*
//*******************************************************************************************************
    $url ="http://stocks.finance.yahoo.co.jp/stocks/detail/?code=" . $index_code;
    $ch  = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $feed = curl_exec($ch);
    curl_close($ch);


    $n = preg_match_all("/class=\"yjSb real\"><span>([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt_indx[0] = $cell[1][0];
    $n = preg_match_all("/class=\"symbol\"><h1>([^<]+)<\/h1>/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt_indx[1] = $cell[1][0];
    $n = preg_match_all("/stoksPrice\"\>([^<]+)/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt_indx[2] = $cell[1][0];
    $n = preg_match_all("/class=\"ico.* yjMSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    $prmdt_indx[3] = $cell[1][0];

    $n = preg_match_all("/<strong>([^<]+)<\/strong><span class=\"date yjSt\">([^<]+)<\/span>/", $feed, $cell, PREG_PATTERN_ORDER);
    if ( $n > 0 ) {
      $dtl_indx[0][0]   = $cell[1][0];
      $dtl_indx[0][1]   = $cell[2][0];
      $dtl_indx[1][0]   = $cell[1][1];
      $dtl_indx[1][1]   = $cell[2][1];
      $dtl_indx[2][0]   = $cell[1][2];
      $dtl_indx[2][1]   = $cell[2][2];
      $dtl_indx[3][0]   = $cell[1][3];
      $dtl_indx[3][1]   = $cell[2][3];
      $dtl_indx[4][0]   = "";
      $dtl_indx[4][1]   = "";
      $dtl_indx[5][0]   = $cell[1][4];
      $dtl_indx[5][1]   = $cell[2][4];
      $dtl_indx[6][0]   = $cell[1][5];
      $dtl_indx[6][1]   = $cell[2][5];
    }
    else {
      $n = preg_match_all("/<strong>([^<]+)<\/strong><span class=\"date yjSt\">/", $feed, $cell, PREG_PATTERN_ORDER);
      $dtl_indx[0][0]   = $cell[1][0];
      $dtl_indx[0][1]   = "";
      $dtl_indx[1][0]   = $cell[1][1];
      $dtl_indx[1][1]   = "";
      $dtl_indx[2][0]   = $cell[1][2];
      $dtl_indx[2][1]   = "";
      $dtl_indx[3][0]   = $cell[1][3];
      $dtl_indx[3][1]   = "";
      $dtl_indx[4][0]   = $cell[1][4];
      $dtl_indx[4][1]   = "";
      $dtl_indx[5][0]   = $cell[1][5];;
      $dtl_indx[5][1]   = "";
      $dtl_indx[6][0]   = $cell[1][6];
      $dtl_indx[6][1]   = "";
    }

    $ret_array = array();

    $ret_array[] =  $n;
    $ret_array[] =  $prmdt_indx;
    $ret_array[] =  $dtl_indx;

    $prmdt_indx = NULL;
    $dtl_indx   = NULL;

    return $ret_array;

}

サンプルプログラム command_index.php:

<?php
require 'finance.php';

$index_code = "998407.O";
$ret_array = index_value( $index_code );
$n              = $ret_array[0];
$prmdt_indx     = $ret_array[1];
$dtl_indx       = $ret_array[2];

  echo "\n主要情報\n";

  echo " Index Name           " . $prmdt_indx[1] . "\n";
  echo " Value at the time of " . $prmdt_indx[0] . " = " . $prmdt_indx[2] . "\n";
  echo " 前日比               " . $prmdt_indx[3] . "\n";

  echo "\n詳細情報\n";

  echo " 前日終値      :" . $dtl_indx[0][0].$dtl_indx[0][1]. "\n";
  echo " 始値          :" . $dtl_indx[1][0].$dtl_indx[1][1]. "\n";
  echo " 高値          :" . $dtl_indx[2][0].$dtl_indx[2][1]. "\n";
  echo " 安値          :" . $dtl_indx[3][0].$dtl_indx[3][1]. "\n";
  if ( $n == 7 ) echo " 出来高        :" . $dtl_indx[4][0].$dtl_indx[4][1]. "\n";
  if ( $n == 6 ) echo " 年初来高値    :" . $dtl_indx[5][0].$dtl_indx[5][1]. "\n";
  if ( $n == 7 ) echo " 52週高値      :" . $dtl_indx[5][0].$dtl_indx[5][1]. "\n";
  if ( $n == 6 ) echo " 年初来安値    :" . $dtl_indx[6][0].$dtl_indx[6][1]. "\n";
  if ( $n == 7 ) echo " 52週安値      :" . $dtl_indx[6][0].$dtl_indx[6][1]. "\n";
?>

出力例:

#php command_index.php

主要情報
 Index Name           日経平均株価
 Value at the time of 15:28 = 14,337.31
 前日比               +111.94(+0.79%)

詳細情報
 前日終値      :14,225.37(11/05)
 始値          :14,155.34(09:00)
 高値          :14,407.69(12:37)
 安値          :14,130.86(09:06)
 年初来高値    :15,942.60(13/05/23)
 年初来安値    :10,398.61(13/01/09)

なお、上述の二つのPHP関数、stock_value()とindex_value()は、ファイルfinance.phpにまとめている。

まとめ: 原始的で力任せのプログラミングながら、(数値データの)抽出が可能になった。上述のサンプルプログラムでは、抽出した全データをYahoo Finance の並びで表示しなおしている。サンプルプログラムを読めば、関数の使い方を理解していただけるものと思っている。

この二つの関数を使って、いろいろ試さねば、と思っているところである。

【読者の皆様にひとこと】ここで示したPHP関数は、個人的責任のもとで使用してください。作成者は、使用形態(Yahoo Financeへのアクセス形態など)ならびに関数の性能について、なんら責任を負うものではありません。


  1. 3 Responses to “Yahoo Finance の株価情報をPHPで抽出してみた”

  2. 初めまして山本と申します。業務アプリ作成をphpで始めたばかりで勉強中な事と私用でデイトレードアプリを作成したいと考えていたので、この情報は大変勉強になります。すみません、一点質問質をさせて頂きたいのですがstock_value()は、どの様なファイルであるべきなのかご教授頂けないでしょうかよろしくお願いします

    By yamamoto on Feb 3, 2016

  3. 申訳ないのですが、質問の意図が、私には、理解できません。

    stock_value()はphp関数のひとつです。ソースは本文に掲載しております。

    なお、この関数については、自己責任にて使用していただくようお願いいたします。

    By yama on Feb 6, 2016

  1. 1 Trackback(s)

  2. Nov 14, 2016: 話題のスマートウォッチのアプリを開発! | 株式会社ロックオン社員ブログ

Post a Comment