日本の個別株の株価データを取得するpythonスクレイピング 法【システムトレード】

今回は、システムを自作するために必須となる株価データの取得方法について紹介します。

 

 

株価データを取得する方法は大きく2つ。

1 お金を払って株価データを買う。
2 株価データが掲載されているサイトをスクレイピング する。

株価データが買えるサイト・株価データが掲載されているサイトは、以下の記事で詳しく紹介されています。

そして、今回紹介するのは2番のスクレイピング による方法です。スクレイピング とはウェブサイト上のデータを取得する手法のことを言います。スクレイピング にはpythonを使いました。
スポンサーリンク
スポンサーリンク

無償で株価データを取得できるサイト一覧

私が把握している無償で株価データを取得できるサイトは以下の3つ。

 

無償のサイトは突然サイトが閉鎖する可能性があります。もしサイトが閉鎖された場合は、有償で使える以下のサイトに乗り換える予定。

 

さらに分類すると、株価データの提供方法には大きく2つの方法があり、

ウェブサイト上に直接データが載っている
ウェブサイト上でダウンロード用のzipファイル等が用意されている

の2パターンがあります。

pythonで株価データをスクレイピング (ダウンロード編)

まずは、zipファイル等でダウンロードするパターンから。以下はサンプルコード。

import requests
import os
import time
import random

path="/Users/保存したいフォルダパス"
year=["2017","2018"]
month=["08","09","10","11","12"]
day=["01","02","03","04","05"]
for y in year:
    for m in month:
        for d in day:
            time.sleep(random.randrange(10,20))
            url_zip = "http://souba-data.com/k_data/"+y+"/"+y[2:4]+"_"+m+"/T"+y[2:4]+m+d+".lzh"
            req_url_zip = requests.get(url_zip, timeout=3.5)
            
            if req_url_zip.status_code == 200:
                
                filename_zip = os.path.basename(url_zip)
                
                with open(path + filename_zip, 'wb') as f:
                    f.write(req_url_zip.content)

サイトは無尽蔵さんを使っています。このサイトで取得できる株価データでは株式分割・併合による調整後株価が取得できないため、このサンプルデータだけで株価分析はできませんのでご注意を。

 

 

zipファイルで提供される場合、まず最初に確認するのはファイル名の規則性。日付がキーになっているケースが多いと思います。ファイル名を指定できないとファイルを取得できないので地味に重要。

 

上のサンプルコードでは以下の部分で規則性に基づくファイル名を指定しています。

url_zip = "http://souba-data.com/k_data/"+y+"/"+y[2:4]+"_"+m+"/T"+y[2:4]+m+d+".lzh"

 

ダウンロードしたいファイル名を指定したら、requests.getでファイルにアクセスします。3.5秒経ってもアクセスできなかったらタイムアウトする仕様。

req_url_zip = requests.get(url_zip, timeout=3.5)

 

以下のif文は、正しくアクセスできたらという意味です。アクセス状況はステータスコードという数字で確認できて、200はアクセス成功を意味しています。祝日などの日付でデータを取得しようとした場合、このif文がないとエラーになります。

詳しくはwikipedia「HTTPステータスコード」参照。

if req_url_zip.status_code == 200:

 

後は以下のコードでデータを保存して完成。

filename_zip = os.path.basename(url_zip)
with open(path + filename_zip, 'wb') as f:
    f.write(req_url_zip.content)

os.path.basenameでディレクトリパスを除いた純粋なファイル名のみ取得して、その名前で指定したフォルダ(最初に定義したpath)にwriteで保存していきます。

 

これを日付でループすれば過去の株価データを取得できるわけです。このままだと、高速で大量にサイトにアクセスし、サイトに負荷をかけてしまうので、

time.sleep(random.randrange(10,20))

で高速処理を防ぎます。私はいつも中断時間はランダムにしています。(別にしなくても良い)

ちなみに、上のコードでは10秒〜20秒ぐらい待つことになっていますが、実際はこんなに待つ必要はありません。

ウェブサイトのHTML上の株価データをスクレイピング

もう1つのパターン。

import urllib
import ssl
import os
import pandas as pd
import time
import random
import glob
import csv
from bs4 import BeautifulSoup
code="取得した銘柄コード"
year="取得する年"
path="保存したいフォルダ(ディレクトリ)パス"
url = "https://kabuoji3.com/stock/"+code+"/"+year+"/" 
ssl._create_default_https_context = ssl._create_unverified_context
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
html = urllib.request.urlopen(req).read() 
soup = BeautifulSoup(html, "html.parser")
time.sleep(random.randrange(3,7))
stockdata= soup.find_all("td")
stockdata = [s.contents[0] for s in stockdata]
stockdata = list(zip(*[iter(stockdata)]*7))
df = pd.DataFrame(stockdata,)
df.columns=['date','open','high','low','close','valume','adjclose']
df.to_csv(path+code+".csv")

株式投資メモさんを利用しています。株式投資メモは、上の例とは違って日付ごとではなく、銘柄ごとに株価データを取得します。CSVファイルを手動でダウンロードもできるので、欲しいデータが少ないのならわざわざスクレイピング する必要はありません。

 

url = "https://kabuoji3.com/stock/"+code+"/"+year+"/" 
ssl._create_default_https_context = ssl._create_unverified_context
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
html = urllib.request.urlopen(req).read()

ますはurllibモジュールでウェブサイトに接続。https接続なのでsslエラー回避のコードを加えています。それとrequest処理の際にユーザーエージェントをfirefoxにしないとエラーが出たのでユーザーエージェントをfirefoxにしています。

 

ユーザーエージェントは、接続するサーバに「私はこんなOSとブラウザを使っていますよー」と伝えるための情報のこと。サーバはユーザーエージェントを受け取るとOSやブラウザに合った最適なウェブサイト表示をしてくれます。

stockdata= soup.find_all("td")
stockdata = [s.contents[0] for s in stockdata]
stockdata = list(zip(*[iter(stockdata)]*7))

BeautifulSoupモジュールで接続したサイトからデータを取得します。

まずは、株式投資メモでは株価データはHTMLのtableタグで構成されているのでtableのtd要素を抽出します。株価データは「日付」「始値」「高値」「安値」「終値」「出来高」「終値調整」の7列のデータがありますが、BeautifulSoupで抽出した<td>データは全て一列のリストで形成されてしまいます。

 

なので、<td></td>を取り除いた後、7列のリストに変換しています。

df = pd.DataFrame(stockdata,)
df.columns=['date','open','high','low','close','valume','adjclose']
df.to_csv(path+code+".csv")

最後はpandasで表にして、列に名前をつけてcsvに保存しておしまい。

 

 

ちなみに、こんな回りくどい方法はせずにスクレイピング を使って直接CSVをDLする方法もあるようです(詳細は以下のサイト)。

RedandWhiteDays

pythonによる個別株スクレイピング まとめ

以上、スクレイピング についてまとめてみました。スクレイピング は、トレードシステムを作る際に最初に必要となるプログラムであり、素人にとってはとてもとても高いハードルになります。私のメモが誰かのために少しでもお役に立てば、幸いです。

 

スクレイピング については、他のサイトでも多数紹介されていたり、書籍もありますので、色々と調べてみると面白いですよ。

コメント