2014年5月21日水曜日

[OCaml]Yahoo financeから株式情報を取得する

HTTPクライアントでコンテンツを取得する方法、正規表現モジュールを使って文字列を抽出する方法が分かったので、
サンプルプログラムとして、Yahoo financeから株式情報を取得する処理を書いてみた。

open Core.Std

(* 指定した株式コード、市場の株式情報をYahoo financeから取得する。 *)
let get_yahoo_stock_info code market =
  let module C = Http_client.Convenience in
  let url = Printf.sprintf "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=%s.%s" code market in
  C.http_get url

let extract pattern str =
  let module P = Pcre in
  let rex = P.regexp pattern in
  (P.extract ~rex:rex str).(1)

(* コンテンツを解析して、市場、会社名、業種、取引単位の組を取得する。 *)
let parse_stock_info content =
  let module P = Pcre in
  let market = extract "<span class=\"stockMainTabName\">(.*?)</span>" content in
  let industory =
    let industory' = extract "yjSb\">(.*?)</dd>" content in
    if String.slice industory' 0 2 = "<a"
    then extract "<a[^>]+>(.*?)<" industory'
    else industory' in
  let company_name = extract "<th class=\"symbol\"><h1>(.*?)</h1></th>" content in
  let unit = extract "<dl class=\"tseDtlDelay\"><dd class=\"ymuiEditLink mar0\"><strong>(.*?)</strong>株</dd>" content in
    (market, company_name, industory, unit)

utopで確認。   

utop[22]> let content = get_yahoo_stock_info "6753" "t" in parse_stock_info content;;                                                                                    
- : string * string * string * string =                                                                                                                                  
("東証1部", "シャープ(株)", "電気機器", "1,000")

結構、スッキリ、簡単に書ける。コードも読みやすい。
ただし、正規表現リテラルがないようなので、\は\\と書かなければならないのが、まどろっこしい。

※2014/5/21現在は、上記の正規表現で株式情報を取得できるが、Yahoo financeのコンテンツの構成が変更されると、取得できなくなる可能性がある。