メインコンテンツへスキップ
見出し画像

Pythonでやってみた7: データ自動取得(Webスクレイピング) ②Web明細の自動ダウンロード

    1.概要

     自分が欲しい情報を自動で取得する技術としてWebスクレイピングがあります。本記事では地下鉄の領収書を自動で取得してみます。

    画像

    2.参考資料

    3.基礎コードの紹介

    3-1.ID・パスワード管理

      ログイン時のユーザー名、パスワードは下記記事を参考として自作モジュール「secretidpass.py」を作成して同じ作業ディレクトリに入れました。

    [secretidpass.py]
    from dataclasses import dataclass
    
    @dataclass
    class ID():
        ID = 'ログインIDを入れてね'
    
    class PASS():
        PASS = 'ログインPASSを入れてね'    

    3-2.要素の取得

     要素の取得は記事「Selenium」で紹介した通りデベロッパーツールを使用しながら事前に取得しました。取得方法は下記の通りです。

    【取得手順】
    ●ブラウザ上でF12を押してデベロッパーツールを呼び出し
    ●|左上のボタン⦅Ctrl+Shift+C⦆で要素を選択できるようにする。
    ●デベロッパーツール内のHTMLを自分で解読したり、下図のように要素をコピーしたりしてほしいデータを抽出する。
    ※自分が楽だったり汎用性が高くなるような要素取得方法を選びます。

    画像

    4.完成品の説明

    4-1.完成コード

    完成コードは下記の通りです。

    [In]
    import os , datetime, time
    from dataclasses import dataclass
    from selenium.common.exceptions import NoSuchElementException
    from selenium import webdriver
    
    #UsernameとPasswordを自作モジュールから取得
    import secretidpass as secret
    username, password = secret.ID().ID, secret.PASS().PASS
    
    #ブラウザの立上
    driver = webdriver.Chrome('chromedriver.exe') #GUI用
    driver.implicitly_wait(5)
    
    url = 'https://www2.pitapa.com/login.html'
    driver.get(url)
    
    #ログイン操作
    driver.find_element_by_name("id").send_keys(username)#ID入力
    driver.find_element_by_name("password").send_keys(password)#PASS入力
    driver.find_element_by_name("login").click() #ログインボタンをクリック
    
    driver.find_element_by_link_text("ご利用代金・明細照会").click()
    
    meisai = driver.find_elements_by_tag_name('select')[1]
    meisai.click()
    
    latestmonth = meisai.text.splitlines()[0]
    meisai.send_keys(latestmonth)
    driver.find_element_by_name("displaySubmit").click() 
    
    #CSVボタンを押す。
    driver.find_element_by_name("csvSubmit").click() 
    
    time.sleep(1)
    driver.quit()
    
    #ダウンロードしたCSVファイルを作業ディレクトリに移動
    import shutil
    
    #推定ファイル名を作成
    today = datetime.datetime.today()
    csvname = today.strftime("%Y%m") + ".csv"
    
    #ダウンロードしたCSVファイルを作業ディレクトリに移動
    path_donwload = "C:/Users/KIYO/Downloads"
    path_csv = os.path.join(path_donwload, csvname)
    
    if os.path.exists(path_csv):
        shutil.move(path_csv, os.getcwd())
        print(f'CSVファイルを{os.path.dirname(path_csv)}->{os.getcwd()}に移動しました。')

    4-2.完成品のアウトプット

     アウトプットとして明細表.csvを作業ディレクトリに保存しました。

    画像

    5.コード説明

    5-1.Webドライバの立ち上げ

     まずはSeleniumでWebドライバを立ち上げます。

    [In]
    import os , datetime, time
    from dataclasses import dataclass
    from selenium.common.exceptions import NoSuchElementException
    from selenium import webdriver
    
    #UsernameとPasswordを自作モジュールから取得
    import secretidpass as secret
    username, password = secret.ID().ID, secret.PASS().PASS
    
    #ブラウザの立上
    driver = webdriver.Chrome('chromedriver.exe') #GUI用
    driver.implicitly_wait(5)
    
    url = 'https://www2.pitapa.com/login.html'
    driver.get(url)

    5-2.pitapaにログイン

     ログイン画面でid, passwordを入力してログインします。

    [In]
    #ログイン操作
    driver.find_element_by_name("id").send_keys(username)#ID入力
    driver.find_element_by_name("password").send_keys(password)#PASS入力
    driver.find_element_by_name("login").click() #ログインボタンをクリック

    5-3.明細画面へ移動/DLボタンを押して立ち下げ

     明細ページに移動して

    [In]
    driver.find_element_by_link_text("ご利用代金・明細照会").click()
    meisai = driver.find_elements_by_tag_name('select')[1]
    meisai.click()
    
    latestmonth = meisai.text.splitlines()[0]
    meisai.send_keys(latestmonth)
    driver.find_element_by_name("displaySubmit").click() 
    
    #CSVボタンを押す。
    driver.find_element_by_name("csvSubmit").click() 
    
    time.sleep(1)
    driver.quit()
    

    5-4.CSVファイルを作業ディレクトリに移動

     私の環境ではCSVファイルに下記ルールがあります。

    【ダウンロードしたCSVファイルのルール】
    ●pitapa+Windowsでは保存したファイルはDownloadフォルダに保存される
    ●ファイル名は「4桁年+2桁月.csv」

     ダウンロードしたCSVファイルを作業ディレクトリを同じ場所に保存するために①CSVファイル名を関数で作成、②CSVが保存されるDownloadフォルダからCSVファイルを|os.getcwd()⦅作業ディレクトリ⦆に移動させました。

    [In]
    path_donwload = "C:/Users/KIYO/Downloads"
    path_csv = os.path.join(path_donwload, csvname)
    
    if os.path.exists(path_csv):
        shutil.move(path_csv, os.getcwd())
        print(f'CSVファイルを{os.path.dirname(path_csv)}->{os.getcwd()}に移動しました。')

    【注意点】
     実用的に問題ないためつけておりませんが、shutil.moveを使用する場合は同じファイル名が移動先に存在するとエラーになります。よって本ケースでは同じ月に同じ処理を2回するとエラーが出ます。


    あとがき

     Webスクレイピングは何個かシリーズを作りたいけど今のスキルでは無理なサイトも多いのでできるようになったらやりたい。

     
     

    KIYO

     
     
    普段は製造業で企画/開発/設計しております。記事はプログラミング・機械学習、IoT関係の記事をメインで作成し、なるべく1つの記事で知りたいことを網羅していきます。内容は学術的より実装・アウトプット(ほしくなるもの)を重視して作成しています。 面白そうな仕事があればやりたいです!

    あなたへのおすすめ