前回、Pythonでマネーフォワードのサイトから口座残高などの情報をスクレイピングしてきて、ポートフォリオを管理するという記事を書きました。今日はその続きで、プログラムの簡単な解説と実装ではまった点などを紹介します。
目次
Seleniumによるスクレピング
今回のコードでは、Seleniumというライブラリを使ってスクレイピングを行いました。Seleniumは、簡単にいうとブラウザを自動操作してくれるライブラリで、今回はGoogle Chromeを自動操作します。そのために、こちらのページからChromedriverを事前にダウンロードし、パスを通しておきます。
プログラムの概要
まずは冒頭でライブラリのインポートを行った後、ブラウザとしてChormedriverを使う宣言をします。
### STEP0:初期設定 # ライブラリのインポート from selenium import webdriver from selenium.webdriver.common.by import By # ブラウザの宣言 browser = webdriver.Chrome()
その後、ページから必要な要素を抽出していきます。Seleniumの各種メソッド(find_element_by_id,find_element_by_class_nameなど)を使って、必要な情報を取得していきます。
### STEP1:マネーフォワードにログイン # URLを設定し、ページへアクセス url = "https://moneyforward.com/users/sign_in" browser.get(url) # find_element_by_idメソッドを使って、メールアドレスを入力する e = browser.find_element_by_id("sign_in_session_service_email") e.clear() e.send_keys(user_name) (中略) #(1)資産内訳の表を取得 table_total_asset = browser.find_element_by_class_name("table-bordered") trs = table_total_asset.find_elements(By.TAG_NAME,"tr") # テーブルの行数を取得
ちょっと面倒だったのが表の読み取りのところで、今回は find_element_by_class_nameメソッドでまず表全体を取得し、その後で find_elements(By.TAG_NAME,”tr”)とすることで、表を各行ごとに分割し、最後に各行に対して”td”タグを探索することで、表の中から必要な情報だけを取得するという方法をとりました。
#(2)預金・現金・仮想通貨の表を取得 # まずは表全体を取得 table_depo = browser.find_element_by_class_name("table-depo") # 表から改行(tr)で分割 trs = table_depo.find_elements(By.TAG_NAME,"tr") nrow = len(trs) for i in range(1,nrow): # 各行について、"td"を目印に列に分割し、欲しい列だけ取得 depo_name = trs[i].find_elements(By.TAG_NAME,"td")[0].text depo_value = trs[i].find_elements(By.TAG_NAME,"td")[1].text
各表から資産の名前と評価額を取得し、それを一旦pd.Seriesに格納し、さらにそれをDataFrameに追加する、という操作を全ての資産に対して行います。その際、資産の名前から、その資産がどのアセットタイプなのかを分類するための関数get_asset_typeを事前に作っておきました。
# アセットリストファイルを参照して、アセット種別を判定する関数 def get_asset_type(name): for i in range(len(asset_type_list.index)): if name == asset_type_list["name"][i]: asset_type = asset_type_list["asset_type"][i] return asset_type
全ての資産の評価額とアセットタイプを取得出来たら、それらをcsvファイルに保存します。さらに、pandasのgroupbyを使って、アセットタイプごとの評価額を集計します。
filename1 = "./daily_asset/" + datetime.date.today().strftime("%Y%m%d") + "_asset-list.csv" df.to_csv(filename1) asset_allocation = df.groupby("asset_type").sum()["value"]
最後に、集計したアセットタイプごとの金額をグラフ化します。
# グラフ化して保存 #※グラフ化の際、凡例を日本語にすると文字化けしたので、英語に変換 asset_allocation = asset_allocation.rename(index={"その他資産":"other","国内債券":"Domestic-bonds","国内株式":"Domestic-stocks","流動資産":"current-assets","海外債券":"foriegn-bonds","海外株式":"foriegn-stocks"}) fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.pie(list(asset_allocation),labels=asset_allocation.index,counterclock=False,startangle=90,autopct="%1.1f%%") title = "date: " + datetime.date.today().strftime("%Y/%m/%d") + " Total: " + '{:,}'.format(sum(asset_allocation)) + "JPY" ax.set_title(title) filename2 = "./daily_asset/" + datetime.date.today().strftime("%Y%m%d") + "_asset-pi-chart.png" fig.savefig(filename2)
感想
初めてPythonでプログラムを組んだのですが、なかなか大変。特に、スクレイピングについては、HTMLやCSSを一から勉強することになったので、大変でした。
いろいろと無駄の多いプログラムのような気もするので、随時改良していこうと思います。
Pythonによるスクレイピングについては、WEB上の情報のほか、以下の本がとても参考になりました。最後まで読み終わったら書評を書きたいと思います。