以前のブログでMoney Forward MEから脱却するためのプロセスを書いた。 hirano00o.hateblo.jp 開発を進める中でスクレイピングをして明細を取得するPythonのライブラリを公開した。 github.com
PyPiはこちら。 pypi.org
何で作成したか
いくつか個人で作成されたツールはあれど、ほとんどがCSVのファイル出力まで実装されている。現状は取得したデータはBigQueryに挿入するので、ファイル出力までされた場合、ファイルを読み込んで整形する手間が増える。そのため、データの取得までを行うライブラリを作成した。
何ができるか
銀行と証券口座、WealthNaviに対して残高や入出金履歴、保有株や投資信託の数や取得単価などが取得できる。
銀行
- 残高の取得
- 入出金履歴の取得
残高は複数の口座を持てる銀行もあるため、口座番号ごとに残高が取得できるように作成している。入出金に関しては、指定した期間と口座番号に対する履歴が取得できる。期間を指定しない場合は、銀行の入出金ページを開いたときに出力される期間のデータが返される(つまりデフォルトの期間は銀行によりけり)。
証券
- 保有株数、取得単価、現在値の取得
- 米国株含む
- 投資信託の保有口数、取得単価、基準価額の取得
- NISA、旧NISA含む
基本的には最小限しか取得していない。例えば損益は、株数 * (現在値 - 取得単価)
で、前日比なども継続して取得していれば算出できる。
そのため、現在値の推移や損益推移を知りたい場合は、継続してデータを取得、保存しておく必要がある。
米国株やETFは、円に直さずドルのままデータを返すため、円で値を知りたい場合は、別途為替レートが必要となる。例えば外為オンラインでは、登録不要でレートがJSON形式で取得できる。
WealthNavi
- 資産クラス、現在価格、損益の取得
WealthNaviは証券口座とは異なり、取得単価や保有数が不明なため、各資産クラスの現在価格と損益をそのまま取得している。WealthNavi上では、ドルでも損益等が見られるが、基本的に入出金は円なので、円でデータを返す。
どの金融機関に対応しているか
現在は下記の金融機関に対応している。
- 銀行
- みずほ銀行
- SBIネット銀行
- 証券
- SBI証券
- その他
- WealthNavi
WealthNaviは、2段階認証をしているユーザが多いと思う。設定を変更せずに利用できるよう、TOTPのコードを入れればログインできるようにしている。
構成と実装
クラスの構造は 各金融機関のクラス
< Bank
or Securities
クラス < Base
クラスの3段階になっており、共通して利用する関数は可能な限り上のクラスにまとめている。例えば、ロード待ちをする関数は全体で使うので Base
クラス、残高を取得する関数は銀行全体で利用するので、abstractmethod
でBank
クラスに定義、実装は各銀行用のクラスで行っている。
スクレイピングは定番のselenium
、beautifulsoup
、pandas
を利用している。SBIネット銀行はJSが大量に利用されているのでかなり苦労した。ローカルで動かす場合とKuberenetes on RaspberryPi5で動かす場合では、selenium
がエラーを出力する箇所が異なり、スクショを見てはどこで操作ができなくなったかを確認し、JSのロード待機させたりと調整をした。
例えば入出金履歴の期間を設定する際、月や日付などをマウスでクリックするが、リストがゆっくりとアニメーションで出てくるため、動作させるスペックによって出てくるまでの時間が異なる。今のところはクリックしてからsleepで待機しているが、できれば別の方法で解決していきたい。
使い方
WebDriverと口座の情報を準備すれば利用できる。WebDriverは、ChromeとFirefoxがよく使われるが、ここではFirefoxを例にとる。
あらかじめ firefox-esr
(もしくはfirefox
)をインストールし、geckodriver
をダウンロードしておく必要がある。
# Apple SiliconのMacの場合 # brew install --cask firefox apt install -y firefox-esr # Apple SiliconのMacの場合 # https://github.com/mozilla/geckodriver/releases/download/v0.34.0/geckodriver-v0.34.0-macos-aarch64.tar.gz wget -qO /tmp/geckodriver.tar.gz \ "https://github.com/mozilla/geckodriver/releases/download/v0.34.0/geckodriver-v0.34.0-linux-aarch64.tar.gz" \ && tar -xzf /tmp/geckodriver.tar.gz -C /usr/local/bin/ \ && rm /tmp/geckodriver.tar.gz
準備ができたら下記のスクリプトを作成して実行する。ユーザIDとパスワード、firefoxのバイナリは各自の環境に合わせて変更する。
from selenium import webdriver from datetime import timedelta, datetime from zoneinfo import ZoneInfo from acctf.bank.sbi import SBI user_id = "" # ユーザIDを入れる password = "" # パスワードを入れる start_date = datetime.now(ZoneInfo("Asia/Tokyo")).date() - timedelta(days=7) end_date = datetime.now(ZoneInfo("Asia/Tokyo")).date() - timedelta(days=1) def create_driver() -> webdriver: options = webdriver.FirefoxOptions() options.add_argument("-headless") options.binary_location = "/usr/bin/firefox-esr" # firefoxの場所はwhich firefoxで調べて適宜変更 service = webdriver.FirefoxService(executable_path="/usr/local/bin/geckodriver") driver = webdriver.Firefox(service=service, options=options) return driver s = SBI(create_driver()).login(user_id, password) hist = s.get_transaction_history( account_number="", start=start_date, end=end_date ) print(f"日付, 取引内容, 金額") for h in hist: print(f"{h.date}, {h.content}, {h.value}") s.logout() s.close()
実行すると下記のように出力される。日付はdatetime.date
なのでデータを取得した後に何か操作する場合でも加工しやすい。
日付, 取引内容, 金額 2023-12-01, ATM引き出し, -10000.0 2024-12-20, 給与, 200000.0
終わりに
今回は銀行や証券口座のデータを取得するライブラリを作成した。利用する際は、金融機関に迷惑がかからないよう、口座がロックされないように注意してください。
本ライブラリは、まだまだ対応していない金融機関や機能が多い。対応してほしい機能や修正したい箇所などがあれば、IssueやPullRequestを作成頂けると幸いです。