とりあえず日記

VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ(いまここ🍄)

イオンモバイルの利用料金をスクレイピングした。(Python+selenium)

経緯

私が契約しているイオンモバイルでは、請求金額を通知するサービスを行っていません。(※)
なので、今まで個人ページで毎月確認していました。

さすがに繰り返しの手作業が面倒になったので、自分の個人ページをスクレイピングして毎月の請求金額をメール通知するようにしました。

(※)イオンモバイルでは請求金額を通知するサービスはありますか? | よくあるご質問|業界最安級 イオンの格安スマホ・格安SIM【イオンモバイル】

以下は、請求金額のページをスクレイピングする最小のソースコードと使い方です。

スクリプトの実行方法

コマンドプロンプトで以下のように実行。
>python.exe aeon_mobile.py お客様ID パスワード

実行結果

コマンドプロンプトに明細をダンプ表示します。
数値が揃っていなくて見にくいですが、細かなことは気にしない!!!
料金は個人情報なので適当に書き換えてます。

**2017年 11月分**
金額(税込)1,234円


**料金明細**
4GBプラン                             123円
追加音声シェア料金                              456円
通話料                          78円
SMS通信料                               9円
イオンでんわ割引通話(国内)                            10円
ユニバーサル料                          11円
イオンでんわ 10分かけ放題                               123円

ソースコード(python+selenium)

aeon_mobile.py というファイル名で保存してください。

"""utf8-bom
イオンモバイルの利用料金をスクレイピングするサンプル。

usage:
python.exe aeon_mobile_pay.py お客様ID パスワード

"""
import sys
from selenium import webdriver
import selenium



#ご利用明細
class Detail(object):
    __slots__ = ("title","money")
    def __init__(self,title="",money=""):
        #プラン名、通話料、通信料・・・
        self.title=title
        #金額
        self.money=money

#月の明細
class InvoiceDetail(object):
    __slots__ = ("month","money","details")
    def __init__(self,month="",money=""):
        #年月
        self.month=month
        #金額(税込)
        self.money=money
        #料金明細
        self.details=[]

    def to_plane_text(self):
        pool=[]
        pool.append("**%s**"%self.month)
        pool.append("金額(税込)%s" % self.money)
        pool.append("\n")
        if not self.details:
            return "\n".join(pool)

        pool.append("**料金明細**")
        for item in self.details:
            pool.append(item.title + "\t\t\t\t" + item.money)

        return "\n".join(pool)


def jump_usage_details_page(driver):
    """ご利用明細のページに切り替える。
    """
    try:
        driver.find_element_by_link_text('ご利用明細').click()
        return
    except(selenium.common.exceptions.NoSuchElementException):
        pass

    #ウインドウ幅が狭くナビゲーションの文字が表示されていない状況なので、
    #左上のボタンをクリックしてメニューを開く。
    driver.find_element_by_xpath('/html/body/div[1]/nav/div/a[2]/i').click()

    #see. https://teratail.com/questions/64684
    elem=driver.find_element_by_xpath('//*[@id="nav-mobile"]/li[2]/a')
    driver.execute_script("arguments[0].click();", elem)


def scraping(driver):
    #
    #ご利用明細のページをスクレイピングする。
    #
    invoice = InvoiceDetail()
    jump_usage_details_page(driver)
    if True:
        #
        #最新の月を処理する。
        #
        invoice.month = driver.find_elements_by_class_name("strong")[0].text
        invoice.money = driver.find_elements_by_class_name("zeikomi")[0].text
        driver.find_elements_by_class_name("link_button")[0].click()
    elif False:
        #
        #1つ前の月
        #
        invoice.month = driver.find_elements_by_class_name("strong")[1].text
        invoice.money = driver.find_elements_by_class_name("zeikomi")[1].text
        driver.find_elements_by_class_name("link_button")[1].click()
    else:
        #
        #2つ前の月
        #
        invoice.month = driver.find_elements_by_class_name("strong")[2].text
        invoice.money = driver.find_elements_by_class_name("zeikomi")[2].text
        driver.find_elements_by_class_name("link_button")[2].click()

    #
    #ご利用明細を取り出す
    #

    #memo
    #[0]    ご利用金額合計(税込)・・・のテーブル
    #[1]    サービス名・・・のテーブル
    details=driver.find_elements_by_tag_name("tbody")[1]
    for tr in details.find_elements_by_tag_name("tr"):
        td = tr.find_elements_by_tag_name("td")
        #サービス名
        service_name = td[0].text
        #金額
        mony = td[1].text
        invoice.details.append(Detail(service_name,mony))

    return invoice


def main(id,pw):
    driver = webdriver.Chrome('C:\selenium\chromedriver')
    driver.get('https://mypage.aeondigitalworld.com/mypage/')

    #ウインドウサイズを小さくする(debug)
    #driver.set_window_size(640,480)

    #ログイン処理
    driver.find_element_by_name('userId').send_keys(id)
    driver.find_element_by_name('password').send_keys(pw)
    o=driver.find_element_by_xpath('//button').click()
    invoice = scraping(driver)
    driver.quit()

    print(invoice.to_plane_text())


if __name__ == '__main__':
    id=sys.argv[1]
    pw=sys.argv[2]
    main(id,pw)

注意

スクレイピングを推奨する意図はありません。
ソースコードなどのご利用は自己責任でお願いします。