outlier

建築士、プログラミング、ライフハック、etc.

Pythonでマネーフォワードをスクレイピングして、ポートフォリオを管理する(その2)

前回、Pythonでマネーフォワードのサイトから口座残高などの情報をスクレイピングしてきて、ポートフォリオを管理するという記事を書きました。今日はその続きで、プログラムの簡単な解説と実装ではまった点などを紹介します。

www.be-outliers.com

Seleniumによるスクレピング

今回のコードでは、Seleniumというライブラリを使ってスクレイピングを行いました。Seleniumは、簡単にいうとブラウザを自動操作してくれるライブラリで、今回はGoogle Chromeを自動操作します。そのために、こちらのページからChromedriverを事前にダウンロードし、パスを通しておきます。

chromedriver.chromium.org

プログラムの概要

まずは冒頭でライブラリのインポートを行った後、ブラウザとして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上の情報のほか、以下の本がとても参考になりました。最後まで読み終わったら書評を書きたいと思います。