あるページに定期的に情報を入力する機会があったのでこれを自動化しました
下準備
環境
AWSにてEC2インスタンスを用意する。
ubuntu20.04(ARM64)
t4g.small
GP3 8GB
22/tcpと3389/tcpを開放
t3aなどのx86_64ではなくARMなのは今回の構築はARMですべて動作可能であり、ARMの方が安くパフォーマンスが高いからである。
デスクトップ環境を構築するものの余計なソフトウェアをインストールしなければ8GBで問題ない
セキュリティーグループではインバウンドルールで22/tcpと3389/tcpを開放する。アウトバウンドルールはデフォルトのまま。
22/TCPはSSH,3389/TCPはRDPにそれぞれ利用する。
パスワードの設定
後述するXRDP接続を行うために、ユーザーubuntuにパスワードを設定する。
EC2インスタンスを立ち上げたときにダウンロードした秘密鍵を用いてSSHを行った後、以下コマンドでパスワードを設定する
$ sudo passwd ubuntu
New password:
Retype new password:
passwd: password updated successfully
パスワードは入力後にコンソールに出力されないが、そのままEnterでよい。
デスクトップ環境構築
ブラウザを実行するにはデスクトップ環境が必須となる。
Ubuntuでは比較的簡単にデスクトップ環境がインストール出来る。
ソフトウェアの更新を行う
sudo apt update
sudo apt upgrade
デスクトップ環境のインストール。インストールにしばらく時間がかかる。
sudo apt -y install ubuntu-desktop
処理完了後に再起動を行う。
sudo reboot
XRDPの導入
デスクトップを構築したので、GUIにアクセスできる方法で遠隔操作する必要がある。
VNCやNICE DCVなどと比較したが、XRDPが導入の手間と接続品質のバランスが丁度良かった。
xrdpのインストールとサービスの再起動
sudo apt -y install xrdp
sudo systemctl restart xrdp
サービスの再起動後にstatusを確認する。Active: active (running)
となっていればOK
systemctl status xrdp
● xrdp.service - xrdp daemon
Loaded: loaded (/lib/systemd/system/xrdp.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-09-14 06:42:01 UTC; 8s ago
Docs: man:xrdp(8)
man:xrdp.ini(5)
Process: 2083 ExecStartPre=/bin/sh /usr/share/xrdp/socksetup (code=exited, status=0/SUCCESS)
Process: 2091 ExecStart=/usr/sbin/xrdp $XRDP_OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 2092 (xrdp)
Tasks: 1 (limit: 2204)
Memory: 716.0K
CGroup: /system.slice/xrdp.service
└─2092 /usr/sbin/xrdp
XRDP接続
接続に利用するクライアントPCがwindowsなら、検索バーにrdpと入力し表示されるリモートデスクトップ接続
を起動する
接続先がwindowsではなくLinuxなので警告が表示されるが、意図した用途のためはい
を選択し続行する
ログイン画面が表示されるため、ユーザー名にubuntu
、パスワードは先程設定したものを入力する。
以下のような初期設定画面が表示される。キーボードやプライバシーの設定があるが、リモートアクセスのためそのまま次へを選択してよい。
ソフトウェアアップデーターからアップデートの通知が来る場合があるが、内容を確認しセキュリティーアップデートで無い限りはアップデートは行わないことにする。
Seleniumでブラウザ操作の自動化
開発機にSelenium IDE導入
ここからはクライアントマシンで作業する。
クライアントはwindows10で作業しているが、macやlinuxでもほぼ同様に作業できる。
ubuntuではデスクトップ環境のインストールに伴いfirefoxがデフォルトでインストールされているため、今回はfireoxを用いて自動化を行う。
pythonで最初からプログラミングを行うのは大変なので、一度Selenium IDEにてコードを作成した後にpythonへと変換することにする。
クライアントPCのfirefoxで以下ページより拡張機能をインストールする
https://addons.mozilla.org/ja/firefox/addon/selenium-ide/
操作の実装
実際にブラウザに対し操作する内容を実装していく。
今回はSelenium JPが公開しているデモサイトexample.selenium.jpを利用する。
これは説明用にデモサイトを利用しているだけなので、実際に対象のページを用いて実装しても良いだろう。
firefoxにインストールしたSelenium IDEをクリックする。
以下の画面が表示される。今回はイチから作成するためCreate a new project
を選択する。
プロジェクトの名前を付ける。特に指定はないが、今回はsample_project1
とする。
Selenium IDEのホーム画面が表示される。
操作の記録を開始するため、右上のREC
ボタンを選択する
プロジェクトのURLを入力する。先程のデモサイトを利用する場合はhttp://example.selenium.jp/reserveApp_Renewal/
と入力する。
対象ページが表示される。自動化したい操作を最後まで入力する。
操作が完了したら起動したタブを閉じる。Selenium IDE
の画面に戻るので、先程選択した右上のREC
ボタンのところにある■をクリックする。
するとTEST NAME
を入力する画面になる。これは今回の一連の操作に名前をつけてね、ということだ。
今回はoperation1
としておく。これも特に指定はないので自由に入力して問題ないが、わかりやすくするために先程のプロジェクト名とは別のものにしておくことが無難だろう。
今回記録した内容は、このSelenium IDEを閉じると消えてしまうためファイルに保存する。
右上の保存ボタンをクリックする。
保存場所とファイル名を確認し、プロジェクトファイルを保存する。
プロジェクトファイルは複数テストケースを作成した場合でも、そのプロジェクト全体で保存し、次に読みだした場合はそのテストケースすべてが読み込まれる。
なお、この保存はwindowsならCtrl+Sでも可能だ。
保存が完了したので、試しに今記録した動作が問題なく実行できるか確認してみる。
Selenium IDEの上部真ん中あたりの三角の再生ボタンをクリックし実行する。
実行ボタンは2つ並んでいるが、左の実行ボタンはプロジェクトに保存されているすべてのテストケースを実行、右の実行ボタンは選択しているテストケースのみを実行する。今回は右の実行ボタンを選択する。
もし途中で意図しない動作を行った場合はここで修正しておく。
今回作成したテストケースはSelenium IDE
から実行することを想定しているため、Pythonに変換する。
Selenium IDE
左上の表示がTests
になっていることを確認し、該当するテストケースにマウスカーソルを合わせると︙
が表示される。これを右クリックする
Python
を選択し、表示を見やすくするために上から2つのチェックボックスを選択しEXPORT
を選択する
なお、ここで生成されるコードはそのままでは使えないので修正する必要がある。
生成直後の素のコード↓
https://github.com/Honahuku/Selenium-Automation/blob/main/test_operation1_original.py
修正したコード↓
https://github.com/Honahuku/Selenium-Automation/blob/main/test_operation1_edited.py
Pythonのプログラムを実行、動作確認(クライアント)
Pythonで必要なライブラリをインストールする
pip install selenium
WARNING: You are using pip version 21.1.3; however, version 21.2.4 is available. You should consider upgrading via the 'c:\python39\python.exe -m pip install --upgrade pip' command.
と怒られる場合がある
windowsなら以下コマンドを管理者権限で起動した
powershellで実行することで解決する
python -m pip install --upgrade pip
以下のソフトをクライアントの環境に応じたもとをダウンロードし、パスの通るディレクトリに展開する
windowsの場合はCドライブ直下にgeckodriver-v0.29.1-win64
でディレクトリを作成しgeckodriver.exe
をその中に入れる。
CLIで2FA
該当ページにアクセスするためにはログインが必要な場合がある。
ログインが必要ない場合は次のリモートマシン(ubuntu)にSelenium導入まで読み飛ばして問題ない
ログインするときの要素としてメールアドレスとパスワードが要求されるが、最近はこれに加えSMSやTOTPによる2FA(二段階認証)/MFA(多要素認証)が実施される。
今回は毎回TOTP(時間ベース)で認証するシステムを自動化することとする。
メールアドレスとパスワードは、
driver.find_element(By.ID, "guestname").send_keys("hoge")
とすることで入力可能だが、問題はTOTPの認証である。
これは秘密鍵と時間をベースに6桁のワンタイムパスワードを発行する仕組みである。
これをCLIから実行する仕組みがあるのでこれを行う。
AWSのubuntuマシンにSSHを行い、以下コマンドを実行する
sudo apt install oathtool
oathtoolというプログラムでTOTP秘密鍵からワンタイムパスワードを発行することが出来る。
使い方は以下の通り。private_key
には実際の秘密鍵をそのまま入力する。
oathtool --totp private_key --base32
これをPythonで実行すると以下の例となる。先の生成したコードと組み合わせて利用してほしい。
import subprocess
#subprocessコマンドでホストOSのコマンドを実行する
#ここではoathtoolコマンドで2FAの秘密鍵からコードを生成し、変数resultへ格納する
result = subprocess.run(["oathtool", "--totp", "private_key", "--base32"],stdout=subprocess.PIPE)
print(result.stdout.decode("utf-8"))
#生成した値に文字列操作し入力可能な形にし、変数numberへ格納する
number = result.stdout.decode("utf-8")
# 13 | type | id=idTxtBx_SAOTCC_OTC | 2FAコードの入力
driver.find_element(By.ID, "idTxtBx_SAOTCC_OTC").send_keys(number)
リモートマシン(ubuntu)にSelenium導入
sudo apt install xvfb python3-pip firefox-geckodriver
pip3 install selenium
動作確認
セットアップしたシェルスクリプトを実行する。正常に実行できなかった場合はXRDP接続を行いトラブルシューティングを行う
なお、
(EE)
Fatal server error:
(EE) Server is already active for display 99
If this server is no longer running, remove /tmp/.X99-lock
and start again.
(EE)
というエラーは
pkill -f "Xvfb :99"
で解消されるので良ければ参考にしてほしい。
インスタンス起動時にプログラムを自動実行
プログラムの実行にはブラウザを起動する必要があるが、これにはGUIが有効な環境が必要なため仮想ディスプレイを用意する。
デスクトップ環境がすでにインストールしてある場合でも、自動実行時にはCUIで実行されてしまうため仮想ディスプレイを有効にしGUIで実行する。
仮想ディスプレイの有効化
sudo apt install xvfb
Xvfb :99 -screen 0 1280x720x16 &
export DISPLAY=:99
自動実行スクリプトの作成
先程作成したpythonのプログラムを自動実行する必要がある。
#!/bin/sh
pkill -f "Xvfb :99"
Xvfb :99 -screen 0 1280x720x16 &
export DISPLAY=:99
python3 ./fill.py
記事の誤植、抜けについて
記事中に一部説明が不足しているところがあった場合は気軽にtwitterのリプライかDMでお問い合わせください。@yosuke_yamakawa
参考文献
下準備
デスクトップ環境のインストールとXRDPのインストール
https://qiita.com/hitobb/items/b44e87e04133dc845265#desktop%E7%92%B0%E5%A2%83%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
Seleniumでブラウザ操作の自動化
コマンドリファレンス
https://qiita.com/oh_rusty_nail/items/77782973b4152992017b
導入について
https://qiita.com/oh_rusty_nail/items/5b584c95e01759c00869