Seleniumで月末に作成する勤務時間表の作成自動化

めんどくさい単純業務を一つ自動化したメモです。

今回ログインが必要なサイトからデータを取得する必用があった為
初めてseleniumを使用しましたが、便利だなあ。

# 自動化の概要
### 自動化する業務内容
二次受けとして参画しているPJにて、
一次受けの会社に対して月末に勤務時間をまとめたExcelを提出する。

### 自動化前の業務手順
1. 日々の業務時間を自社サイトに記録
1. 月末になったら、自社サイトから日時の出退勤時間を目視で参照
1. 一時受け指定のExcelに転記
1. 担当者に提出

上記2, 3の出退勤時間の転記を自動化しました。

### 自動化後の業務・処理手順
1. 日々の業務時間を自社サイトに記録
1. コピペで新規Excel作成し、`python WorkingTimeGet.py` 実行
<dl>
  <dt>(1)【元データ取得】</dt>
    <dd>①Seleniumで自社サイトへアクセスし、ID, PASSを入力</dd>
    <dd>②ログインボタンをクリックし、ログイン</dd>
    <dd>③勤務時間の照会ページへ遷移</dd>
    <dd>④HTMLを取得（Webページは閉じる）</dd>
  <dt>(2)【データ加工、Excel作成】</dt>
    <dd>①Tableタグから各項目を取得し、DataFrameにつっこむ</dd>
    <dd>②Excelを開き出退勤時間をセット</dd>
    <dd>③Excelを保存して終了</dd>
</dl>
1. 担当者に提出

# 使用技術
Python (3.8.5)
selenium (3.141.0)
beautifulsoup4 (4.9.3)
pandas (1.1.3)
openpyexl (3.0.5)

# ソースコード

<details><summary>ソースコード</summary><div>

``` python:WorkingTimeGet.py
import sys
import os
import re # 正規表現
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_binary # パスを通すためのコード
from bs4 import BeautifulSoup
import pandas as pd
import openpyxl as excel

loginpage = {ログインページのURL}
targetpage = {ログイン後、勤務時間の照会ページのURL}
idtxt = {ID}
passtxt = {PASS}
print('処理開始')

print('ファイル名を入力してください。')
file = input()

# ファイルの存在確認
if not os.path.isfile(file):
    print('ファイルが存在しません。')
    sys.exit()

# ================================================================================
# 対象Webページからデータを取得
# ================================================================================
# Chromeを開く
option = Options()
option.add_argument('--headless')
driver = webdriver.Chrome(options=option)
driver.get(loginpage)

# 要素が見つかるまでの最大待機時間を設定
driver.implicitly_wait(5)

# ID/PASSを画面に入力
id = driver.find_element_by_id({ID入力欄の要素のid})
id.send_keys(idtxt)

password = driver.find_element_by_id({PASS入力欄の要素のid})
password.send_keys(passtxt)

# ログインボタンをクリック
login_button = driver.find_element_by_name({ログインボタンの要素のid})
login_button.click()

print('データ取得中……')

time.sleep(1)

# 勤務時間照会画面を開く
driver.get(targetpage)

# htmlを取得
html = driver.page_source
driver.quit() # ブラウザを閉じる

print('データ取得完了')

# ================================================================================
# データ加工
# ================================================================================
print('データ加工中……')
# HTMLをパースする
soup = BeautifulSoup(html, 'lxml')

# DataFrameを作成する
columns = ["日付", "区分", "出勤", "退勤", "休憩", "合計", "残業", "控除", "プロジェクト", "タスク", "作業種別", "時間"]
df = pd.DataFrame(columns = columns)

# テーブルを取得
table = soup.findAll("table", {"name":{セレクタ名}})[0]
trs = table.findAll("tr")

# DataFrameに行追加
for tr in trs:
    tds = tr.findAll("td")
    rowname = tds[0].get_text().strip()
    df2 = pd.DataFrame(data = [[
        tds[0].get_text().strip()
        ,tds[1].get_text().strip()
        ,tds[2].get_text().strip()
        ,tds[3].get_text().strip()
        ,tds[4].get_text().strip()
        ,tds[5].get_text().strip()
        ,tds[6].get_text().strip()
        ,tds[7].get_text().strip()
        ,tds[8].get_text().strip()
        ,tds[9].get_text().strip()
        ,tds[10].get_text().strip()
        ,tds[11].get_text().strip()
    ]], columns = columns)
    df = df.append(df2, ignore_index = True)

print('データ加工完了')

# ================================================================================
# Excelに書き込み
# ================================================================================
print('Excel書き込み開始……')
# Excelを開く
wb = excel.load_workbook(file, keep_vba=True)
ws = wb[{シート名}]

row = 1

for workfrom, workto in zip(df['出勤'], df['退勤']):
    # 出退勤時間をセット
    ws.cell(row=row, column=2).value = workfrom
    ws.cell(row=row, column=3).value = workto

    # 中略…（その他の処理）

    row += 1

wb.save(file)
print('Excel書き込み完了')

print('処理終了')
```
</div></details>

# 参考
* [python × seleniumでID/PASS入力必要な画面に自動ログインしてみた](https://qiita.com/shota-nekoneko/items/64bbd0c2f534d20e7b77)
* [【完全版】PythonとSeleniumでブラウザを自動操作(クローリング／スクレイピング)するチートシート](https://tanuhack.com/selenium/)