LoginSignup
15
20

More than 5 years have passed since last update.

selenium webdriverを使ってWebページを自動操作する

Last updated at Posted at 2017-08-19

概要

勤怠入力にAttendance Proというソフトを使っているのですが、日々の入力が面倒ということでseleniumのweb driverを使って自動化してみました。
非常に稚拙な方法ですが、あまりこういうことに慣れていないので、初めの一歩として。
また自分以外の人、Python環境のない人も使えるようにexe化します。

(8/21追記)
最初はChromeのwebdriverを使用していましたが、それだとブラウザが毎回立ち上がるため、ヘッドレスブラウザとしてPhantomJSを使用する形に変えています。
PhantomJSはこちらからダウンロードして、環境変数Pathにphantomjs.exeのあるフォルダのパスを指定しておく。

環境と準備

主なソフトウェア環境は以下。
OS: Windows 10
Python: 2.7.12
Selenium: 3.5.0
PyInstaller: 3.2.1
PhantomJS: 2.1.1

自分はselenium, pyinstallerなどがなかったので、pipでインストール。

pip install selenium
pip install pyinstaller
pip install ctype

コード

出勤と退勤を別のファイル(exe)にしています。ここでは出勤だけですが、ほぼ一緒です。

attendancepro_start.py
import sys
import os
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.support import ui
from selenium.webdriver.common.keys import Keys
import time
from ctypes import *

# exeで配布するために、ユーザ名とパスワードは都度指定する形に
username = sys.argv[1]
password = sys.argv[2]

user32 = windll.user32

def page_is_loaded(driver):
    return driver.find_element_by_tag_name("body") != None

# ブラウザのドライバを読み込む。
# driver = webdriver.Chrome("./chromedriver.exe") 元々はChromeで実施していたが以下に変更
driver = webdriver.PhantomJS(service_log_path=os.path.devnull)
# 対象ページを読み込ませる。まずはログインページ。
driver.get("https://attendance.cvi.co.jp/LogOn.aspx")
wait = ui.WebDriverWait(driver, 10)
wait.until(page_is_loaded)

# 読み込んだら、find_element_by_xpathで指定して要素を取得し、入力を与える。
# あらかじめ、ブラウザにてwebページのソースを表示して、入力したいフォームなどのIDを探しておく。
email_field = driver.find_element_by_xpath("//*[@id=\"txtUserID\"]")
email_field.send_keys(username)

company_field = driver.find_element_by_xpath("//*[@id=\"txtCompanyCode\"]")
company_field.send_keys("xxx")

password_field = driver.find_element_by_xpath("//*[@id=\"txtPassword\"]")
password_field.send_keys(password)

# 全部入力したら、画面遷移
password_field.send_keys(Keys.RETURN)
wait = ui.WebDriverWait(driver, 10)
wait.until(page_is_loaded)
time.sleep(5)

# 同様に、入力したい箇所のIDを指定して、入力を与える。
# ここではsubmit要素の状態(enabled/disabled)で場合分けしている。
# またMessageBoxでどちらの分岐になったか、わかるようにしている。
if driver.find_element_by_xpath("//*[@id=\"ctl00_ContentMain_btnWebStartTime\"]").is_enabled():
    driver.find_element_by_xpath(
        "//*[@id=\"ctl00_ContentMain_btnWebStartTime\"]").click()  # Send day start
    user32.MessageBoxA(
        0,
        "Start done",
        "AttendancePro",
        0)
else:
    user32.MessageBoxA(
        0,
        "Start already done",
        "AttendancePro",
        0)

# 終わったら、ブラウザとショートカット(後述)のウィンドウを閉じて終了。
driver.close()
os.system('taskkill /fi "WindowTitle eq attendancepro_start"')
sys.exit()

exe化

以下のコマンドでexe化。icoは適当に。
pyinstaller --clean -F --icon=xxx.ico attendancepro_start.py

この時点で、できたexeを以下でテスト。
attendancepro_start.exe <ユーザ名> <パスワード>
Chrome driverを使う場合はexeと同じフォルダに配置しておく。

配布後に必要なアクション

いちいちコマンドプロンプトで実行するのは面倒なので、exeをショートカット化して実行する形を想定。
引数はショートカットのプロパティにて指定します。
image

この方法だと最後にコマンドプロンプトのウィンドウが残るため、最後にtaskkillでウィンドウを消しています。
たぶん普通こんな方法はとらないのだと思いますが、簡単にできる方法がわからなかったので、こうしています…。

雑感

かなり楽にはなりました。また、これでwebページをpythonで操作する、ということを覚えたので何かに応用できれば。
Python3.xでもほぼ大丈夫なのですが、途中で使っているMessageBoxAにて最初の文字しか表示されません。MessageBoxWなら大丈夫なのですが、今後は2.xで文字化けします。どうせexeでの使用を想定しているので、今回は目をつぶります。

参考

Seleniumにてウェブページの要素を指定する方法

exe化したものに後から変数を指定する方法

メッセージボックスのパラメータ

windowsのショートカットを実行後に、ウィンドウを閉じる

MessageBoxにて最初の文字しか表示されない

15
20
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
15
20