読者です 読者をやめる 読者になる 読者になる

株も歩けば犬に当たる

ブラックSlerで働くSEが株やPythonや思ったことについて書いています。

第1回 pandasで株価をスクレイピング 〜S◯I証券風のチャートを描いてみる〜  

S◯I証券風のチャートを自作してみました。

f:id:doz13189:20160822042547p:plain

doz13189.hatenablog.com

チャートを描くまでの工程を段階を踏みながら、載せていきたいと思います。

第一回 pandasで株価をスクレイピング
今回は、pandasで株価をスクレイピングしてきて、データにまとめようと思います。
今回使う、サイトはこちらです。

info.finance.yahoo.co.jp


以下のコードで、指定した期間の株価をもってくることができます。

import pandas
import datetime

def scraping_yahoo(code, start, end, term):
	base = "http://info.finance.yahoo.co.jp/history/?code={0}.T&{1}&{2}&tm={3}&p={4}"

	start = str(start)
	start = start.split("-")
	start = "sy={0}&sm={1}&sd={2}".format(start[0], start[1], start[2])
	end = str(end)
	end = end.split("-")
	end = "ey={0}&em={1}&ed={2}".format(end[0], end[1], end[2])
	page = 1

	result = []
	while True:
		url = base.format(code, start, end, term, page)
		df = pandas.read_html(url, header=0)
		if len(df[1]) == 0:
			break

		result.append(df[1])
		page += 1
	result = pandas.concat(result)
	result.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']

	return result


if __name__ == "__main__":
	company = 4312

	EndDate = datetime.date.today()
	StartDate = EndDate - datetime.timedelta(days=30)

	data = scraping_yahoo(company, StartDate, EndDate, "d")
	print(data)


データは、こういった形で出力されます。

f:id:doz13189:20160826163417p:plain


ここから、コードの解説です。

まずは、はじめにURLを分解します。

http://info.finance.yahoo.co.jp/history/?code=5002.T&sy=2016&sm=2&sd=27&ey=2016&em=8&ed=26&tm=d

↓こんな感じに。後で.formatで整えるので{}を使っています。

base = "http://info.finance.yahoo.co.jp/history/?code={0}.T&{1}&{2}&tm={3}&p={4}"

{0} = 証券コード(5002)
{1} = 表示したい株価の日付の始まりの日(2016-2-27)
{2} = 表示したい株価の日付の終わりの日(2016-8-26)
{3} = ページ数(1)
各{}にはこれらが入ります。

{1}と{2}の日付の入力は、2016-6-2というフォーマットで統一しているため、コードを走らせる際にこの「-」を取り除く必要があります。
そのため、split("-")で取り除いています。
splitで取り除いたあとは、リスト形式になります。
ちょうど、[2016],[6],[2]の順になっているので、リストの[0][1][2]の順に入れてやります。

def scraping_yahoo(code, start, end, term):
	base = "http://info.finance.yahoo.co.jp/history/?code={0}.T&{1}&{2}&tm={3}&p={4}"

	start = str(start)
	start = start.split("-")
	start = "sy={0}&sm={1}&sd={2}".format(start[0], start[1], start[2])
	end = str(end)
	end = end.split("-")
	end = "ey={0}&em={1}&ed={2}".format(end[0], end[1], end[2])
	page = 1

これでURLの分解が終わりました。

次に、これを使ってページ先のデータを取り込んでいきます。
サイトを見てもらえれば、わかると思いますが、データはテーブル形式で格納されています。
1ページ目から順に読み込んで、読み込んだらpageに+1をして、ページ数分をwhileで回すという方法をとっています。
読み込んだページにデータがなければ、breakするようになっています。

読み込んだデータは、result =[]に追加され、そのあとにpandas.concatによって一つのデータとしてまとめられています。

	result = []
	while True:
		url = base.format(code, start, end, term, page)
		df = pandas.read_html(url, header=0)
		if len(df[1]) == 0:
			break

		result.append(df[1])
		page += 1
	result = pandas.concat(result)
	result.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']

	return result

最後です。
証券コードをcompanyに格納しています。
そして、データの欲しい期間をdatetimeを使って、作っています。
EndDateに今日の日付を入れて、StartDateに今日から30日前の日付を入れています。

if __name__ == "__main__":
	company = 5002

	EndDate = datetime.date.today()
	StartDate = EndDate - datetime.timedelta(days=30)

	data = scraping_yahoo(company, StartDate, EndDate, "d")
	print(data)

以上で、解説を終わります。
出力したデータをcsvに出力するなり、matplotlibでプロットするなり、あとは自由です。
ちなみに私は、このデータを使ってローソク足を作成しています。
ローソク足を作成するにはもう2つか3つくらい工夫が必要ですので、続きが気になる方はどうぞこちらで確認してください。

doz13189.hatenablog.com


ちなみに第3回はこちらです。

doz13189.hatenablog.com