Pythonを利用して業務を効率化していますか?しかし業務の効率化でPythonを使うために勉強したいけれど実際にどこで利用すればいいのかわからないままPythonのコードの書き方忘れてしまったとという人もいるのでしょうか。本文書ではせっかく学習したPythonを業務に活用できるようにSelenium(セレニウム)というツールを使ってChromeブラウザを制御してNTTドコモの携帯の料金を確認することができるMy docomoから利用内訳のPDFをダウンロードするための手順を解説したいと思います。

最近では業務ではWEBから請求書を含む各種伝票、データをダウンロードする機会も増えてきていますし個人でも携帯、クレジット、電子マネー、Suica、光熱費などWEBから明細をダウンロードする場所は多々あります。ぜひ身近なところからPythonを使って効率化につなげてください。

動作確認はWindows10のPython3を利用して行っています。

環境の構築

Windows10でPythonがインストールされている状態から開始します。Pythonが入っていない場合はインストールを行ってください。

python -Vでバージョン確認を行います。ここでは3.9.6を利用しています。


> python -V
Python 3.9.6

Seleniumのインストール

pipコマンドを利用してSeleniumのインストールを行います。


 % pip install selenium

chromedriverのインストール

Chromeを操作するためにはSeleniumとは別にブラウザ専用のドライバが別途必要になります。現在インストールされているChromeのバージョンに対応したドライバを利用するためChromeのバージョンを確認します。

Firefoxなど別のブラウザを利用する場合はそれぞれに対応したドライバのインストールが必要となります。
fukidashi

Chromeブラウザを起動して画面右上の縦に3つ●が並んだボタンをクリックして、ヘルプのメニューを開き”Google Chromeについて”を選択します。

Chromeのメニューを表示
Chromeのメニューを表示

Google Chromeについてを開くとバージョンが表示されます。現在のバージョンが最新版で92.0.4515.159であることがわかります。最新版でない場合はこの画面でアップデートが行われると思うでアップデート後のバージョンを確認してください。

Chromeのバージョンを確認
Chromeのバージョンを確認

バージョンが確認できたらChromeDriver(https://chromedriver.chromium.org/downloads)サイトにアクセスを行います。Current ReleasesにChromeのバージョンとダウンロードリンクを確認することができます。

Chromeのドライバの確認
Chromeのドライバの確認

先ほどChromeのバージョンが92.04515であることを確認したのでChromeDriver 92.0.4515.107のリンクをクリックしてください。ダウンロード一覧が表示されるので各OSにあったものをダウンロードしてください。Windowsを利用しているのでchromedriver_win32.zipをクリックします。

ドライバのダウンロードリンク一覧
ドライバのダウンロードリンク一覧

ダウンロードが開始され終了するとダウンロードフォルダにダウンロードファイルが保存されます。デスクトップをダウンロード先にしている場合は下記のようにアイコンが表示されます。圧縮されているので解凍を行ってください。

ダウンロードファイル
ダウンロードファイル

中には拡張.exeの実行ファイルが保存されているので任意の場所にそのファイルを保存してください。ドライバのファイルはどこか決められた場所に保存されるわけではなくPythonのコード中で保存したファイルのパスを直接設定するこになります。

解凍後の実行ファイル
解凍後の実行ファイル

ここまでの作業でChromeブラウザをPythonから操作するための環境の構築は完了です。ここからPythonコードを記述していきます。

My docomoを利用して動作確認

Seleniumを説明しているネットの記事はたくさんありますが実際存在するサイトを利用して実践的に説明しているものは多くはありません。今回は皆さんが利用する機会が最も多いであろう携帯電話のサイトであるMy docomoを利用させてもらいます。これから作成するコードを利用することで利用内訳のPDFをダウンロードすることが可能となります。最近では紙の請求書は廃止されWEBサイトからダウンロードするという形式も増えてきたと思いますのでそれらのデータを取得するための自動化のヒントになればと思います。

My docomoへのアクセス

pythonを実行するコードは任意の場所に作成してください。ここではデスクトップ上にautomationというフォルダを作成し、docomo.pyファイルを作成します。driverフォルダを作成し、その下に先ほどダウンロードして保存したchromedirverのexeファイルを保存します。

My docomoのサイトのURLはhttps://www.nttdocomo.co.jp/mydocomo/です。seleniumを利用してアクセスするために下記を記述します。pipでインストールしたseleniumからwebdriverをimportして、Chromeメソッドの中にはダウンロードしたchromedriverのパスの設定を行います。getメソッドでMy docomoのURLを指定します。


from selenium import webdriver

chrome = webdriver.Chrome(executable_path='./driver/chromedriver.exe')
chrome.get("https://www.nttdocomo.co.jp/mydocomo/")

docomo.pyを実行するとChromeブラウザが自動で起動してMy docomoのページが表示されます。ブラウザのURLの下に”Chromeは自動ソフトウェアによって制限されています”。

My docomoのページ表示
My docomoのページ表示

それ以降の処理が終わりなのでこの後は何も変化はありません。Pythonコードを実行したターミナルにはメッセージが表示されるかもしれませんがコードが動いていればとりあえず無視してください。

ボタンをクリック

My docomoを利用するためにはログインを行う必要があります。ページを開いただけではログインフォームも表示されていないため”ログインする”ボタンをクリックする必要があります。

ボタンをクリックするために”ログインする”ボタンの要素にアクセスする必要があります。ブラウザのデベロッパーツールを利用して要素の確認を行います。ボタンはaタグの中にログインするという文字列が入っているのでfind_element_by_partial_link_textメソッドを利用します。リックでメソッドに指定する文字列の一部が一致する要素を取得してくれます。取得した要素をクリックするのでclickメソッドを追加します。


chrome.find_element_by_partial_link_text('ログインする').click()
要素を取得するメソッドについてはSeleniumのドキュメントに記述されています。サイトへのリンクについては”ドキュメントサイトの確認”の章で説明を行っているので参考にしてください。
fukidashi

先程起動したブラウザを停止し再度docomo.pyを実行します。My docomoのページが開いた後、自動でクリックが行われログイン画面が表示されます。

ログインページ表示
ログインページ表示

input要素のへの入力

ログイン画面が表示されたので次はdアカウントのIDを入力する必要があります。ブラウザのデベロッパーツールを利用してinput要素を確認するとinput要素にid属性が設定されておりDi_Uidと設定されているのでidを使って要素にアクセスします。今度はfind_element_by_idメソッドを利用しています。


chrome.find_element_by_id("Di_Uid")

取得した要素に文字を入れたい場合はset_keysメソッドを利用することができます。jondoe@docomo.ne.jpを設定しています。


chrome.find_element_by_id("Di_Uid").send_keys("johndoe@docomo.ne.jp")

ここまで再度docomo.pyを実行します。dアカウントのIDのinput要素に設定したjohndoe@docomo.ne.jpが表示されるのが確認できます。

input要素に文字列入力
input要素に文字列入力

dアカウントIDを入力後は”次へ”ボタンをクリックしなければならないので次へボタンの要素を確認します。ボタンにはclassが設定され、その一つにnextactionを持っているので今後はclass名を利用します。class名で要素が取得できたらclickメソッドを実行します。classを使って要素を取得したい場合はfind_element_by_class_nameメソッドを利用できます。


chrome.find_element_by_class_name("nextaction").click()

docomo.pyを実行します。次へボタンをクリックすることができましたが指定したdアカウントのIDが存在しないため”IDが誤っています。”というエラーが表示されました。次へ進むためには正しいdカウントが必要となります。

エラーが表示
エラーが表示

各自が持っている正しいアカウントIDを利用して進めるとパスワードの画面が表示されます。パスワードの入力であればdアカウントIDのiput要素の様にidにはDi_Passを持っているで要素を取得しset_keysメソッドでパスワードを入力することができます。しかし2段階認証を行っている場合は携帯電話にSMSでセキュリティコードが送信されてくるのでその値が都度変更になるために対応することができません。

パスワード画面
パスワード画面

ここで諦めてしまいそうですが通常のブラウザでMy docomoにアクセスした場合は一度My docomoにアクセスを行うことでブラウザにIDとパスワードを保存することができるためブラウザを起動してアクセスするとdアカウントIDとパスワードが入力された状態で表示されます。

ログインするアカウントが設定された状態なのでログインするボタンをクリックします。

ログインするdアカウントIDの確認
ログインするdアカウントIDの確認

ブラウザに保存された情報が入力された状態で表示されます。

IDとパスワードが入力済
IDとパスワードが入力済

パスワード確認ボタンをクリックするとそのまま認証を追加してMy docomoのページが表示されます。

My docomoページ
My docomoページ

プロフィール情報の設定

docomo.pyを実行すると一度コードを利用してdアカウントIDを入力したとしてもdアカウントIDもクリアされ値を保持することができません。ブラウザに保持している情報を利用するためにChromeブラウザが持つ プロフィール情報を利用します。 プロフィール情報には閲覧履歴、パスワードといった情報が保存されています。

ブラウザを起動してURLのバーにchrome://versionを入力します。実行するとプロフィールパスが表示されています。ここにプロフィール情報が保存されているためこのパスを利用する必要があります。

プロファイル情報
プロファイル情報

プロフィール 情報はオプションとして設定を行うために下記のように記述して設定を行うことができます。profile_pathの[ユーザ名]には現在利用しているWindowsのユーザ名を指定し、プロフィールパスの最後のDefaultは抜いて設定を行ってください。


options = webdriver.chrome.options.Options()
profile_path = 'C:\\Users\\[ユーザ名]\\AppData\\Local\\Google\\Chrome\\User Data'
options.add_argument('--user-data-dir=' + profile_path)
chrome= webdriver.Chrome(executable_path='./driver/chromedriver.exe',options=options)

これで以前パスワードが保存されたサイトにseleniumからアクセスするとIDとパスワードが入力された状態で表示されます。

待機時間を設定

通常はブラウジングする際は人がページを見る時間や入力するのに時間がかかりますがプログラムを使って処理を行うと人ではできないスピードで処理が実行されるためサーバへ負荷をかける場合やページが表示されていないのに次々と処理を実行しようとします。そのため何かの処理を実行したら一定時間待って処理を行うようにします。プロフィールの設定、 待機時間 を設定してmy docomoのページまでの処理を記述すると下記のようになります。

待機時間を設定するためにtimeをimportし、time.sleep(3)と設定すると待機時間が3秒となります。


from selenium import webdriver
import time

options = webdriver.chrome.options.Options()
profile_path = 'C:\\Users\\Reffect\\AppData\\Local\\Google\\Chrome\\User Data'
options.add_argument('--user-data-dir=' + profile_path)
chrome = webdriver.Chrome(executable_path='./driver/chromedriver.exe',options=options)

chrome.get("https://www.nttdocomo.co.jp/mydocomo/")
time.sleep(3)

chrome.find_element_by_partial_link_text('ログインする').click()
time.sleep(3)

chrome.find_element_by_class_name("nextaction").click()

docomo.pyを実行すると実行したターミナルには以下のメッセージが表示されます。他のブラウザが起動している場合に表示されるので開いているChromeブラウザがある場合はすべて停止して実行してください。


selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir

各処理で待機を行いページを開くまでに少し時間がかかりますが最終的にはMy docomoのページが表示されるはずです。ここまででMy docomoのログイン処理をseleniumを利用して行えるようになります。

My docomoページ
My docomoページ

ドキュメントサイトの確認

ここまででいくつかの処理をプログラムを使って処理をしましたがやってきたことは要素を取得して、その要素に対して何か実行を行うといった2つだけです。要素の取得については3つほど紹介しましたがそれ以外の方法はドキュメントから確認することができます。ドキュメントサイトのURLはhttps://selenium-python.readthedocs.io/です。

seleniumドキュメント
seleniumドキュメント

要素の取得については左側のメニューの4.Locating Elementsを確認します。複数の要素を取得できるfind_elementsもありますがid, name, tag, classなどを利用することができます。find_elementsはリスト要素やテーブルの要素など同じタグを利用して表示している要素に対して活用することができます。find_elementとfind_elementsは区別して利用してください。

4.Locationg Elements
4.Locationg Elements

利用内訳がダウンロードできるURLを確認

利用内訳がダウンロードできるページまでseleniumを利用して移動することができますがダウンロードできるURLが知ることができればボタンを押しながら目的のページに移動するための処理は必要なくなります。実際にボタンをクリックしながら確認していくとご利用料金確認サイトのページからダウンロードできることがわかります。そのページのURLはhttps://www.mydocomo.com/dcm/dfw/bis/guide/ebilling/gkfap001.srvです。

料金の確認ページ
料金の確認ページ

今月である8月はまだ確認していないために利用内訳のダウンロードを行うことができません。過去の次がダウンロードできるの6月,7月,8月と表示されているタブから7月をクリックしてください。

ページの中頃に利用明細をダウンロードするボタンが表示されここをクリックすると7月の利用内訳のPDFをダウンロードすることができます。

ダウンロードリンク
ダウンロードリンク

PythonのコードではMy docomoにログインが完了した後、 ご利用料金確認サイトに移動して、7月のタブをクリックして、利用内訳をダウンロードするという大きく3つの処理が必要となります。これを記述すると下記のようなコードになります。


# ご利用料金確認サイトに移動
chrome.get("https://www.mydocomo.com/dcm/dfw/bis/guide/ebilling/gkfap001.srv")
time.sleep(3)

# 7月のタブをクリック
chrome.find_element_by_name('usage-04').click()
time.sleep(3)

# 利用内訳をダウンロード
chrome.find_element_by_partial_link_text('利用内訳をダウンロードする').click()

タブについてはデベロッパーツールを見るとliタグのname属性にusage-01,usage-02,…usage-05が設定されており今月(8月)を除いた4カ月分の内訳をダウンロードできるようです。今回は前の次のデータのみダウンロードするのでname属性のusage-04を持つ要素をfind_element_by_nameを使って取得しています。

実行するとダウンロードフォルダにPDFが保存されるはずです。たった数行のデータで目的のPDFをダウンロードすることができるようになりました。

ドロップダウンのメニューを選択

PDFのダウンロードの流れの中では出てきませんでしたがサイトの中ではリンクやボタンのクリックだけではなくドロップダウンメニューを選択する必要がある場合もあります。

ドロップダウンメニュー
ドロップダウンメニュー

その場合はSelectをimportとして、上記のドロップダウンメニューであればselect_by_index(1)なので7月(8月請求)を選択することが可能になります。


from selenium.webdriver.support.select import Select

//略
dropdown  = chrome.find_element_by_id("mydcm_payment_selector_02_month")
select = Select(dropdown)
select.select_by_index(1)

まとめ

PythonのSeleniumを利用することで数行のコードを記述しただけでサイトから料金内訳のダウンロードを行うことができました。これは月に一度だけの処理なのでブラウザで手動でもそれほど時間がかかるものではありませんが毎日ダウンロードする必要がある場合は定型作業を自動化することは確実に自動化につながります。ぜひ興味がある人はチャレンジしてみてください。