PythonとSeleniumを使って楽天銀行の明細取得（CSVダウンロード）する

PythonとSeleniumを使って、楽天銀行サイトにログインして明細データを取得（CSVダウンロード）する方法を解説します。サンプルコード全文も記事の後半に載せているので参考になれば幸いです。

※2021/03/27時点の情報です。

## 環境
- Windows 10
- Python 3.8
- Selenium 3.141.0

## はじめに
ログインのみのサンプルは、こちらの記事に書きました。

https://qiita.com/yoshi2045/items/2fff5bf5f0fa763f7104

この記事では、CSVダウンロードする部分にポイントを絞って解説していきます。全体の流れはサンプルコード全文でご確認ください。

なお、お試しで書いた状態なので、クラス化もメソッド化もしてません。エラー処理も考慮してない状態です。いずれキレイに書き直したいと思っています。


## プロファイル設定をする
まず、ファイルをダウンロードするための準備を行います。

```python
# ダウンロードフォルダ
# 相対パス指定はできない模様
# dl_folder = r"..\dl-data"
dl_folder = r"ダウンロードフォルダのパスを指定"

# オプション設定
options = FirefoxOptions()

# ヘッドレスモードを有効にしたい場合は以下を追加
# options.add_argument('--headless')

# プロファイル設定
fp = webdriver.FirefoxProfile()

# ダウンロードフォルダ指定
# 0: デスクトップ、1:システム規定のフォルダ、2:任意の指定フォルダ
fp.set_preference("browser.download.folderList", 2)
fp.set_preference("browser.download.dir", dl_folder)

# ダウンロードマネージャウィンドウを表示させない
fp.set_preference("browser.download.manager.showWhenStarting", False)

# MIMEタイプを設定
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream;text/csv")
```

今回のサンプルでは、ドライバーにFirefoxを使っているので、webdriver.FirefoxProfile()でプロファイル設定オブジェクトを取得し、以下の設定をしました。

- ダウンロードフォルダを任意のフォルダに指定
- ダウンロードマネージャウィンドウを表示させない
- MIMEタイプを設定

ダウンロードマネージャウィンドウというのはこういうやつです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/50f30706-e804-b043-e810-c466cb355bc4.png)

このウィンドウは、Seleniumではコントロールできないようなので、非表示にします。

MIMEとは、Multipurpose Internet Mail Extensionsの略で、ファイルの種別を明示するための情報です。これも指定してあげないと上手くCSVファイルをダウンロードできないようです。

設定画完了したら、Firefoxを起動する際の引数に渡してあげます。

```python
# Firefoxを起動する
browser = Firefox(options=options, firefox_profile=fp)
```

## 対象画面まで遷移させる
[こちらの記事](https://qiita.com/yoshi2045/items/2fff5bf5f0fa763f7104)を参考にログインまでできたら、続けてCSVをダウンロードする画面まで遷移させます。

楽天銀行の場合、ログイン後の画面からCSVダウンロードできるページまでの遷移は以下の通りです。


◆ログイン後の画面
「入出金明細」リンクをクリック
![Rakuten_Bank.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/84acc87b-7f29-c46a-4647-4a632be8d3ef.png)

◆入出金明細画面へ遷移
![Rakuten_Bank(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/1f2040e5-f3db-2e96-1ede-d48c520d4364.png)

ページスクロールしていくと、明細行の下にCSVダウンロードボタンがあります。ここをSeleniumを使って操作していきます。

![Rakuten_Bank(2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/98c54fe4-2679-ca91-bf73-4021261ffcba.png)

ログイン後画面から入出金明細画面へ遷移するコードはこちらです。

```python

# 入出金明細画面へ遷移
browser.find_element_by_link_text("入出金明細").click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.ID, "FORM_DOWNLOAD:_idJsp556"))
)

# 画面遷移できたか確認（画面キャプチャ取る）
browser.save_screenshot("../screenshots/bank_rakuten/meisai.png")
```

入出金明細のリンクを指定するのに今回はfind_element_by_link_text()を使用しました。できればfind_element_by_id()のように、確実に要素を特定できるメソッドのほうが好ましいのですが、id定義されていない要素の場合は上記のように他の方法を使って要素を特定する必要があります。

## 期間を指定してダウンロード実行

期間を指定する入力欄があるので、それぞれの値を入力し、CSVダウンロードボタンを特定したうえでクリック実行するとファイルダウンロードが開始されます。

```python
# ダウンロード対象期間を指定
# TODO: 期間の値はプログラム実行時にパラメータ入力する等、可変値にしたほうがよい
from_y = "2021"
from_m = "01"
from_d = "01"
to_y = "2021"
to_m = "01"
to_d = "31"

# ダウンロード対象期間入力
e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_FROM_YEAR")
e.clear()
e.send_keys(from_y)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_FROM_MONTH")
e.clear()
e.send_keys(from_m)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_FROM_DAY")
e.clear()
e.send_keys(from_d)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_TO_YEAR")
e.clear()
e.send_keys(to_y)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_TO_MONTH")
e.clear()
e.send_keys(to_m)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_TO_DAY")
e.clear()
e.send_keys(to_d)

# ダウンロード実行
browser.find_element_by_id("FORM_DOWNLOAD:_idJsp556").click()

# 処理終了
browser.quit()
```

もう少し丁寧に書くとすると、ダウンロード実行後、完了するまで待機するような処理も入れるといいと思います。



## サンプルコード全文
```python
#
# 楽天銀行サイトへログイン＆CSVダウンロード
#

import json
from selenium import webdriver

from selenium.webdriver import Firefox, FirefoxOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

# 設定ファイルからログイン情報を取得
login_info = json.load(open("login_info.json", "r", encoding="utf-8"))

# ログインサイト名
site_name = "bank_rakuten"

# ログイン画面URL
url_login = login_info[site_name]["url"]

# ユーザー名とパスワードの指定
USER = login_info[site_name]["id"]
PASS = login_info[site_name]["pass"]

# ダウンロードフォルダ
# 相対パス指定はできない模様
# dl_folder = r"..\dl-data"
dl_folder = r"ダウンロードフォルダのパスを指定"

# オプション設定
options = FirefoxOptions()

# ヘッドレスモードを有効にする
options.add_argument('--headless')

# プロファイル設定
fp = webdriver.FirefoxProfile()

# ダウンロードフォルダ指定
# 0: デスクトップ、1:システム規定のフォルダ、2:任意の指定フォルダ
fp.set_preference("browser.download.folderList", 2)
fp.set_preference("browser.download.dir", dl_folder)

# ダウンロードマネージャウィンドウを表示させない
fp.set_preference("browser.download.manager.showWhenStarting", False)

# MIMEタイプを設定
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream;text/csv")

# Firefoxを起動する
browser = Firefox(options=options, firefox_profile=fp)

# ログイン画面取得
browser.get(url_login)

# 入力
e = browser.find_element_by_id("LOGIN:USER_ID")
e.clear()
e.send_keys(USER)
e = browser.find_element_by_id("LOGIN:LOGIN_PASSWORD")
e.clear()
e.send_keys(PASS)

# ログイン
button = browser.find_element_by_id("LOGIN:_idJsp43")
button.click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.ID, "footer-copyright"))
)

# ログインできたか確認（画面キャプチャ取る）
browser.save_screenshot("../screenshots/bank_rakuten/home.png")


# 入出金明細画面へ遷移
browser.find_element_by_link_text("入出金明細").click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.ID, "FORM_DOWNLOAD:_idJsp556"))
)

# 画面遷移できたか確認（画面キャプチャ取る）
browser.save_screenshot("../screenshots/bank_rakuten/meisai.png")

# TODO: 期間の値はプログラム実行時にパラメータ入力する等、可変値にする
# ダウンロード対象期間
from_y = "2021"
from_m = "01"
from_d = "01"
to_y = "2021"
to_m = "01"
to_d = "31"

# ダウンロード対象期間入力
e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_FROM_YEAR")
e.clear()
e.send_keys(from_y)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_FROM_MONTH")
e.clear()
e.send_keys(from_m)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_FROM_DAY")
e.clear()
e.send_keys(from_d)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_TO_YEAR")
e.clear()
e.send_keys(to_y)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_TO_MONTH")
e.clear()
e.send_keys(to_m)

e = browser.find_element_by_id("FORM_DOWNLOAD:EXPECTED_DATE_TO_DAY")
e.clear()
e.send_keys(to_d)

# ダウンロード実行
browser.find_element_by_id("FORM_DOWNLOAD:_idJsp556").click()

# 処理終了
browser.quit()
```