(v_20)Python 株価データをExcelファイルに書き込み

株価データをExcelファイルに書き込み
記事(v_19)でopenpyxlを使ってExcelファイルの書込みを試しました。
何か実用的に使えないかと考えてみました。
今年から新NISAを始めています。これをきっかけに単元未満株を少し購入しています。
単元未満株はauカブコム証券ではプチ株、SBI証券ではS株とかの名称です。
株価をサイトで確認するのが面倒に思っていました。
せっかくBeautifulSoupやSelenumuでデータの抽出やopenpyxlを使ってExcelファイルの書込みを少しかじったので、これら応用して、株価データをExcelファイルに記録しようと思います。
※Pythonの開発環境はThonny、ブラウザーはFirefox、実際の表計算はLibreOffice Calcを使用しています。
株価スクレイピングサイト
Yahooファイナンスでのスクレイピングは以下のように禁止されています。

株価データを取得できるサイトを探してみました。
株価データを取得できるサイトを探してみました。
MONEY BOXサイト「https://moneybox.jp/robot.txt」で確認すると自動取得を禁止していないようなので、ここから株価を取得しようと思います。ただしMONEY BOXサイトの株価はリアルデータではないです。確定済の値が表示されています。

MONEY BOXサイトの株価取得はBeautifulSoupとSelenimuの組み合わせでスクレイピングしました。※SelenimuのドライバーにはFirefoxを使っています。
データ取得だけなので記事(v_13)と同じように、Seleniumでページのhtmlソースデータを取得しBeautifulSoupで構造解析します。
株銘柄のページは「https://moneybox.jp/investment/summary.php?t=’+’株コード’」で開きます。
例えばトヨタ自動車ならコードが’7203’なので「https://moneybox.jp/investment/summary.php?t=7203」で開きます。

このトヨタ自動車のページから株価を抽出してみます。
ThonnyのShellで確かめながら進めます。
SeleniumでページのhtmlソースデータをFirefoxをドライバーにして取得します。
オプションでheadlessを指定してFirefox画面は表示しないようにしています。
>>> from selenium import webdriver
>>> options = webdriver.FirefoxOptions()
>>> options.add_argument("-headless")
>>> driver = webdriver.Firefox(options=options)
The version of firefox cannot be detected. Trying with latest driver version
>>> url='https://moneybox.jp/investment/summary.php?t=7203'
>>> driver.get(url)
>>> html=driver.page_source
>>> html
'<html><head>\n<meta charset="utf-8">\n<meta name="keywords"
content="世界の株価,リアルタイム,トヨタ自動車株価,">\n<meta name="description"
content="トヨタ自動車の株価情報やチャート、PTS株価、ADR株価、掲示板、動画、
企業情報、関連ニュースなど多数の情報をまとめました。">
\n<title>トヨタ自動車の株価と関連情報トップ:MONEY BOX</title>
省略
BeautifulSoupで構造解析します。
>>> soup=BeautifulSoup(html, "html.parser")
>>> soup
<html><head>
<meta charset="utf-8"/>
<meta content="世界の株価,リアルタイム,トヨタ自動車株価," name="keywords"/>
<meta content="トヨタ自動車の株価情報やチャート、PTS株価、ADR株価、掲示板、
動画、企業情報、関連ニュースなど多数の情報をまとめました。" name="description"/>
<title>トヨタ自動車の株価と関連情報トップ:MONEY BOX</title>
省略
必要なデータを抽出してリストデータk_datします。
>>> k_dat=[]
コードと銘柄名の部分「【7203】トヨタ自動車」を抽出します。
Firefoxで画面を右クリックして「調査」を選択してタグを調べます。

class=”top”で指定できそうです。
>>> tgt=soup.find(class_="top")
>>> dat=tgt.text
>>> dat
'【7203】トヨタ自動車'
抽出したデータをk_datに収めます。
>>> k_dat.append(dat)
次に株価等のデータを取得します。同様にFirefoxの「調査」で調べると、class=”under”で指定できそうです。
>>> tgt=soup.find(class_="under")
>>> dat=tgt.get_text("|", strip=True)
>>> dat
'3,290|円|↑|+27 (+0.83%)|tweet|2024-06-28'
データを整理してリストデータにします。
>>> dat=dat.replace('(','|')
>>> dat=dat.replace(')','')
>>> dat=dat.split('|')
>>> dat
['3,290', '円', '↑', '+27 ', '+0.83%', 'tweet', '2024-06-28']
前日比が0の場合、’↑’が抜けるようなので’*’を追加することにしました。
>>> if len(dat)==6:
dat.insert(2,'*')
必要なデータをk_datに収めます。
>>> k_dat.append(dat[0])
>>> k_dat.append(dat[3])
>>> k_dat.append(dat[4])
>>> k_dat.append(dat[6])
>>> k_dat
['【7203】トヨタ自動車', '3,290', '+27 ', '+0.83%', '2024-06-28']
他の銘柄も抽出するので、銘柄のコードリストを作成して、以下のように繰り返し取得後にFirefoxのドライバーを終了するようにしました。
複数の銘柄データと日付を加えたリストデータ(m_dat)が下記になったとします。
>>> m_dat=[['【7203】トヨタ自動車', '3,290'], ['【9201】日本航空', '2,538.5'],
['【9101】日本郵船', '4,682'], ['【1332】ニッスイ', '862.8'], ['2024-06-28']]
このデータを以下のようにエクセルファイルに書込むとします。
そのためにコード、銘柄、データ(日付+各株価)を各々にまとめたリストデータにしてエクセルファイルに書込みします。
たぶんもっとよい方法があると思いますが。

日付を登録します。
>>> dy=m_dat.pop()
>>> d_valu.append(dy[0])
コード、銘柄名、日付+各株価を各々のリストデータにします。
>>> d_code=['コード']
>>> d_name=['銘柄']
>>> for dat in m_dat:
#dat=['【7203】トヨタ自動車', '3,290']
dd=dat[0].replace('【','')
dd=dd.split('】')
#['7203', 'トヨタ自動車']
d_code.append(dd[0]) #'7203'
d_name.append(dd[1]) #'トヨタ自動車'
d_valu.append(dat[1]) #'3,290'
コードデータ
>>> d_code
['7203', '9201', '9101', '1332']
銘柄名データ
>>> d_name
['トヨタ自動車', '日本航空', '日本郵船', 'ニッスイ']
日付+各株価データ
>>> d_valu
['2024-06-28', '3,290', '2,538.5', '4,682', '862.8']
これでエクセルファイルに書込むデータの整理はできました。
記事(v_19)を参考にしながらopenpyxlを使ってエクセルファイルに書込んでみます。
エクセルファイル名を’kabu_01b.xlsx’、シート名を’kabu’にしました。
スクリプトは以下にしました。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 株データ
d_code=['コード', '7203', '9201', '9101', '1332']
d_name=['銘柄','トヨタ自動車', '日本航空', '日本郵船', 'ニッスイ']
d_valu=['2024-06-28', '3,290', '2,538.5', '4,682', '862.8']
from openpyxl import Workbook
file_name='kabu_01b.xlsx'
sheet_name='kabu'
#エクセルファイル作成 Workbook、create_sheet
wb=Workbook()
wb.create_sheet(sheet_name)
wb.save(file_name)
wb.close()
#エクセルファイルを読み出し
from openpyxl import load_workbook
wb=load_workbook(file_name)
ws=wb[sheet_name]
#リストデータを横方向(カラム方向)に書込み
def xls_Write(x_cell, y_cell, d_list):
col=0
for dat in d_list:
ws.cell(y_cell, col+x_cell).value=dat
col=col+1
#コード、銘柄名の書込み
xls_Write(2, 2, d_code) # x, y, list-data
xls_Write(2, 3, d_name)
#日付データの変換
from datetime import datetime
d_valu[0]=datetime.strptime(d_valu[0],'%Y-%m-%d')
#日付+各株価データの書込み
xls_Write(2,4,d_valu)
#上書き保存
wb.save(file_name)
wb.close()
実行結果
エクセルファイルを開いて確認します。書込みが出来ています。

スクリプト
以上をまとめスクリプトを以下のようにました。
株データの追記をするためエクセルファイルの「A1」に書込み数を記録するようにしています。
この値から書込み行を指定するようにしています。A列のA4~には連番を書込みました。
シートのフォントを変更して保存するようにしています。
bg_02_kabu_03b.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#import urllib.request
from selenium import webdriver
from bs4 import BeautifulSoup
import time
##
# サイトからデータを取得
# Selenium ---------------------------
options = webdriver.FirefoxOptions()
options.add_argument("-headless")
print('--headless-- webdriver.Firefox')
#Firefox WebDriverのインスタンスが作成
driver = webdriver.Firefox(options=options)
time.sleep(1)
d_url=['7203','9201','9101','1332'] #データ取得する銘柄コード
m_dat=[] #取得データの保管
for k_num in d_url:
url='https://moneybox.jp/investment/summary.php?t='+k_num
driver.get(url)
time.sleep(1)
html=driver.page_source
#BeautifulSoup parser
soup=BeautifulSoup(html, "html.parser")
k_dat=[] #銘柄ごとのデータ
tgt=soup.find(class_="top")
d_name=tgt.text #コード 銘柄名
#print(d_name)
#'【7203】トヨタ自動車'
k_dat.append(d_name)
tgt=soup.find(class_="under")
dat=tgt.get_text("|", strip=True)
#print(dat)
dat=dat.replace('(','|')
dat=dat.replace(')','')
dat=dat.split('|')
#['3,290', '円', '↑', '+27 ', '+0.83%', 'tweet', '2024-06-28']
# if len(dat)==6:
# dat.insert(2,'*')
#print(dat)
k_dat.append(dat[0])
#print(k_dat)
#['【7203】トヨタ自動車', '3,290']
m_dat.append(k_dat) #各銘柄の取得データを追加
m_dat.append([dat.pop()]) #最後に日付データを追加
#print(m_dat)
#driverの終了処理
driver.delete_all_cookies()
driver.close()
driver.quit()
print('driver.quit---\n')
##
# 書込用のデータに変更
# 書込用データ d_code、d_name、d_valu
dy=m_dat.pop() #日付値を取得
d_valu=[] #株価
d_valu.append(dy[0]) #日付値を追加
d_code=['コード']
d_name=['銘柄']
for dat in m_dat:
dd=dat[0].replace('【','')
dd=dd.split('】')
#['7203', 'トヨタ自動車']
d_code.append(dd[0])
d_name.append(dd[1])
d_valu.append(dat[1])
# 書込むデータ値の表示
print(d_code)
print(d_name)
print(d_valu)
##
# エクセルファイルに書込む
from openpyxl import Workbook
from openpyxl import load_workbook
import os
file_name='kabu_01b.xlsx'
sheet_name='kabu'
# Excelファイルの準備
# Excelファイルが無い場合は新規にWorkbookオブジェクトを作成して保存
if os.path.isfile(file_name)==False:
print(f'Not file create_file={file_name}')
wb = Workbook()
wb.save(file_name)
# Excelファイルがある場合はロードしてWorkbookオブジェクトを作成
wb=load_workbook(file_name)
if sheet_name not in wb.sheetnames:
print(f'Not Sheet create_sheet={sheet_name}')
wb.create_sheet(sheet_name)
wb.save(file_name)
# if "Sheet" in wb.sheetnames:
# wb.remove(wb["Sheet"])
# wb.save(file_name)
wb.close()
# Excelファイルの読み書き
print(f'{file_name} : {sheet_name}')
wb=load_workbook(file_name)
ws=wb[sheet_name]
def xls_Write(x_cell, y_cell, d_list):
col=0
for dat in d_list:
ws.cell(y_cell, col+x_cell).value=dat
col=col+1
#y_cnt 書込み数(データ数) 初回なら1を設定、コード、銘柄名を書込み
#y_cnt=ws.cell(1,1).value #ws['A1'].value
y_cnt=ws['A1'].value
#print('A1=',y_cnt)
if (y_cnt==None) or (y_cnt==0):
y_cnt=int(1)
#コード、銘柄名の書込み
xls_Write(2,2,d_code) # col-x,row-y
xls_Write(2,3,d_name)
print(f'Data_Num= {y_cnt}')
#日付データ(変換して書込)
from datetime import datetime
d_valu[0]=datetime.strptime(d_valu[0],'%Y-%m-%d')
#日付+各株価データの書込み
xls_Write(2,3+y_cnt,d_valu)
#データ数をA列に記録 ws.cell(y-row, x-col).value=dat
ws.cell(3+y_cnt, 1).value=y_cnt
ws.cell(1, 1).value=y_cnt+1 # ws['A1']=y_cnt
#フォント変更
from openpyxl import load_workbook
#ワークブックの読み込み
wb=load_workbook(file_name)
ws=wb[sheet_name]
from openpyxl.styles import Font
# font = Font(name='Meiryo UI', size=12, bold=True, color='ff0000')
#表全体のフォントを変更する
font = Font(name='Meiryo UI', size=11)
for row in ws:
for cell in row:
ws[cell.coordinate].font = font
#上書き保存
wb.save(file_name)
wb.close()
実行結果
実行した結果です。
同日に実行してもデータは追加されて行きます。
同日なら追加しないように工夫した方が良さそうです..

ThonnyのShell部には以下のような表示がされました。
>>> %Run bg_02_kabu_03b.py
--headless-- webdriver.Firefox
The version of firefox cannot be detected. Trying with latest driver version
driver.quit---
['コード', '7203', '9201', '9101', '1332']
['銘柄', 'トヨタ自動車', '日本航空', '日本郵船', 'ニッスイ']
['2024-07-03', '3,325', '2,557.5', '5,047', '866']
kabu_01b.xlsx : kabu
Data_Num= 7
まとめ
サイトから株価データを抽出してExcelファイルに書き込みすることができました。
簡単に確認、記録が出来るので便利だと思います。












