Python＋SeleniumでVIEWカードの明細をCSVダウンロードする

PythonとSeleniumを使って、VIEWカードサイトにログインして明細データを取得（CSVダウンロード）する方法を試してみました。

サンプルコード全文も記事の後半に載せているので参考になれば幸いです。そしてもっと上手いやり方ご存知の方いらっしゃったらぜひ教えてください＾＾

※2021/04/20時点の情報です。

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


## はじめに
ログインまでの部分や、webdriverのプロファイル設定に関する部分については、以下記事をご確認ください。

https://qiita.com/yoshi2045/items/f699fee4ecb22feade22

↑ログインするところまでのサンプルです。（本記事のサンプルコードにもログイン部分あります）

https://qiita.com/yoshi2045/items/be739680bceb2f2df6a2

↑サンプルのwebdriverは、Firefoxを使っています。CSVダウンロードするにあたって、Firefoxのプロファイル設定が必要なので、そのあたりを解説しています。

## 対象画面まで遷移させる
まず、VIEWカードのログイン後TOP画面から明細ダウンロード画面までどういう経路で遷移できるかを確認してみます。

＜画面フロー＞

1. TOP画面
2. ご利用明細照会画面 ← ここでCSVダウンロード

上記フローで目的の画面まで遷移できることが分かりました。では続いて、具体的に各画面ごとの遷移処理を見ていきましょう。

◆ログイン後のTOP画面

![20210419-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/551eb2c4-a50a-0422-2193-685ee4b3056a.png)

TOP画面からご利用明細照会画面への遷移は、画面上部のメニュータブもしくはトップタブ内にある「ご利用明細照会」ボタンをクリックします。

```python
# ご利用明細照会画面へ遷移
browser.find_element_by_xpath("//a[@id='LnkV0300_001Top']/img").click()
```


◆ご利用明細照会画面

ご利用明細照会画面に遷移後、対象のカードと対象月を選択します。

![20210419-002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/7e520e71-fd54-6e23-49f0-f7c1397233f8.png)

私が保持しているカードは1つのみなので、カード選択部分の操作は割愛しました。

対象月の選択の仕方ですが、VIEWカードの場合は全てボタンとして表示されているので、CSVダウンロードしたい月のボタンをクリックします。

```python
# 指定月の明細表示
# TODO:指定年月は可変にする
year = "2021"
month = "04"
browser.find_element_by_link_text("{0}年{1}月".format(year, month)).click()
```

ボタン名のリンクテキストが年と月の組合せになっているので、format()を使ってリンクテキストを作成して指定しています。上記サンプルでは年も月も固定値ですが、実際プログラムを組む時には任意の値を設定できるようにしたほうがよいですね。

ちなみに他のサイトだとリストボックスになっていて、そこから年月日を選択するやり方が多いです。


## CSVダウンロード実行

対象月の選択しボタンクリックすると、明細が表示されます。

![20210419-003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459893/e2f1f3d4-de3d-c22e-cad6-8e177b3fadf8.png)

明細データがある場合は「明細CSVダウンロード」ボタンが表示されるので、このボタンをクリックするとダウンロードが実行されます。

```python
# CSVダウンロード実行
browser.find_element_by_id("BtnCsvDownloadTop").click()
```

これで無事、CSVダウンロードできると思います。

以上、Python＋SeleniumでVIEWカードの明細をCSVダウンロードする方法でした！


## サンプルコード全文

```python
#
# Viewカードサイトへログインして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 = "card_view"

# ログイン画面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"
# TODO: ダウンロードフォルダのパスは適宜変更してください
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("id")
e.clear()
e.send_keys(USER)
e = browser.find_element_by_id("pass")
e.clear()
e.send_keys(PASS)

# ログイン
button = browser.find_element_by_xpath("//input[@type='image']")
button.click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.CLASS_NAME, "details_left_01"))
)
print("ログイン成功")

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

# ご利用明細照会画面へ遷移
browser.find_element_by_xpath("//a[@id='LnkV0300_001Top']/img").click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.ID, "decision"))
)
print("ご利用明細照会画面遷移成功")

# 指定月の明細表示
# TODO:指定年月は可変にする
year = "2021"
month = "04"
browser.find_element_by_link_text("{0}年{1}月".format(year, month)).click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.ID, "BtnCsvDownloadTop"))
)
print("ご利用明細表示成功")

# CSVダウンロード実行
browser.find_element_by_id("BtnCsvDownloadTop").click()

# ログアウト画面へ遷移
browser.find_element_by_link_text("ログアウト").click()

# ページロード完了まで待機
WebDriverWait(browser, 10).until(
    ec.presence_of_element_located((By.ID, "Logout"))
)
print("ログアウト画面遷移成功")

# ログアウト
browser.find_element_by_id("Logout").click()

# 処理終了
browser.quit()

print("=== All done! ===")
```