LoginSignup
2
3

More than 3 years have passed since last update.

SeleniumでEラーニングの受講者情報更新を自動化

Posted at

こんばんは。二度目の投稿の@0yanです。
今回はSeleniumでEラーニングの受講者情報更新を自動化しました(社内業務自動化の一環です)。
Seleniumでクリックできない問題にドハマったので、同じことで悩んでいる人の一助になれば幸いです。
なお、本記事は私と同じく、Selenium初心者の方を対象としております。

やったこと

Seleniumで
1.Eラーニングの管理者ログインページに遷移
2.ログイン
3.受講者一覧ページに遷移
4.受講者詳細ページに遷移
5.上司という項目を更新、登録ボタン押下(受講者一覧ページに戻る)
6.上記4,5を約250回繰り返す
という作業を自動化しました。

自動化の背景

私の所属会社では、求人情報サイトを運営する某大手企業のEラーニングを利用しております。

  • コンテンツが充実している(考え方やコンピテンシーからプログラミングや語学まで幅広いコンテンツが揃っている)
  • 管理者(人事)側で、受講者毎にオススメ講座を設定出来る
  • 受講報告メールがイケてる(「会社に対する提案」という項目があり、そこから組織改善につながるアイディアが得られる)

といった良い点が沢山あるにも関わらず、同業他社と比べて安価で非常に気に入っております。

しかしながら、この素晴らしいEラーニングにも一点だけ不満があります。それは受講者一括更新機能の対象項目に、一部の項目が入っていないこと。

問題の項目は(受講者の)上司という項目なのですが、これを設定しないと受講報告メールが上司に飛ばないのです。
受講報告メールが上司に飛ばないと困るので、当然、設定するわけですが、会計年度が切り替わるときに発生する大規模な体制変更の際は、上司の変更作業だけで一日が終わってしまいます。
しかも、クリックするだけの簡単なお仕事。価値を生まない、誰でもできる作業に段々嫌気が差してきます。
そこで今回、Python版Seleniumを使ってこの作業を自動化することにしたのです。

環境

Windows 10 Home(64bit)
Google Chrome 75.0.3770.90
Python 3.6.8(Anaconda3をインストール)
chromedriver-binary 74.0.3729.6.0
selenium 3.141.0

ライブラリ周り

SeleniumとWebDriver(今回はChromeDriver)のインストール、Seleniumの基本操作については、@memakura さんの記事を参考にさせて頂きました。

Python + Selenium で Chrome の自動操作を一通り

@memakura さん、ありがとうございました!

boss_update.py
# coding: utf-8

import csv
import time

import chromedriver_binary
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

コーディング

やったこと(再掲)

Seleniumで
1.Eラーニングの管理者ログインページに遷移
2.ログイン
3.受講者一覧ページに遷移
4.受講者詳細ページに遷移
5.上司という項目を更新、登録ボタン押下(受講者一覧ページに戻る)
6.上記4,5を約250回繰り返す
という作業を自動化しました。

1.Eラーニングの管理者ログインページに遷移

管理者ログインページにアクセスします。

boss_update.py
def main():
    driver = webdriver.Chrome()
    driver.get('管理者ログインページのURL')

2.ログイン

テキストボックスにログインIDとパスワードを入力し、ログインボタンを押下します。

boss_update.py
    driver.find_element_by_xpath('ログインIDテキストボックスのxpath').send_keys('ログインID')
    driver.find_element_by_xpath('パスワードテキストボックスのxpath').send_keys('パスワード')
    driver.find_element_by_xpath('ログインボタンのxpath').click()

3.受講者一覧ページに遷移

管理者ページTOPから受講者一覧ページに遷移します。

boss_update.py
    driver.find_element_by_xpath('受講者一覧ページへの遷移ボタンのxpath').click()

4.受講者詳細ページに遷移

受講者一覧ページは、下図のようなカードが沢山並んだ構造となっており、受講者氏名に受講者詳細ページへのリンクがはられています。
また、受講者氏名のxpathは「~[@id="student_受講者番号"]~」のようになっています。

image.png

なので今回は、下図のようなCSVをフォーマットとし、xpath内の受講者番号を可変とすることで、受講者一覧ページ内の特定の受講者氏名をクリックできるようにしました。

image.png

boss_update.py
with open(file='.\\update_boss.csv', mode='r', encoding='utf-8-sig', newline='') as csv_file:
    reader = csv.DictReader(csv_file)
    for row in reader:
        try:
            student_number = row['受講者番号']
            # 受講者氏名を受講者番号で検索してクリック
            driver.find_element_by_xpath('~[@id="student_{}"]~'.format(student_number)).click()
        except:
            # 受講者番号が受講者一覧ページにない場合はログ残す
            print('受講者番号検索エラー({})'.format(row['受講者番号']))

5.上司という項目を更新、登録ボタン押下(受講者一覧ページに戻る)

with open ステートメントの続きです。エラーとなっていなければ、受講者詳細ページに遷移しています。
このページで苦戦しました・・・!

苦戦した点

1.テキストボックスを選択できない
上司を入力するテキストボックスがページ最下部にあり、前ページから遷移してきた直後は見えない状態になっています。
それが理由なのかはわかりませんが、find_element_by_xpathメソッドだけではテキストボックスを選択できませんでした。
そのため、execute_scriptメソッドを使い、JavaScriptでページ最下部までスクロール。
これで解決できました。

2.候補者リストをクリックできない
テキストボックスに上司の氏名を入力すると、登録されている受講者リストから候補者の氏名が出てきます(下図参照)。

image.png

しかし、なぜか候補者リストをクリックできませんでした。
ページのソースを見ると、selectタブになっていたため、「プルダウンリストのように、Selectクラスのインスタンスを生成して選択する必要があるのか?」と考え、それを試しましたがうまくいかず・・・。
四苦八苦しましたが、候補者リストが出てきてから1秒待ったらクリックできました。

boss_update.py
        try:
            # JavaScriptでページ最下部までスクロール
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

            # 現在の上司を消す(余裕をみて3回バックスペース)
            for i in range(3):
                driver.find_element_by_xpath('~[@id="edit_student_{}"]~'.format(student_number)).send_keys(Keys.BACK_SPACE)

            # 上司を入力し、候補者リストを表示させる
            boss = row['上司']
            driver.find_element_by_xpath('~[@id="edit_student_{}"]~'.format(student_number)).send_keys(boss)

            # 候補者リストをクリック(1秒以上待たないとエラーになる)
            time.sleep(1)
            driver.find_element_by_xpath('候補者リストのxpath').click()

            # 登録するボタンをクリック
            driver.find_element_by_xpath('~[@id="edit_student_{}"]~'.format(student_number)).click()
        except:
            print('上司更新エラー({})'.format(row['受講者番号']))

        # 一時停止
        time.sleep(1)

さいごに

Qiitaへの記事投稿をTwitterでもつぶやいております。
フォローして頂けますと幸いです(ユーザー名は@0yan_sです)。

長文にも関わらず、最後までご覧頂き誠にありがとうございました。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3