LoginSignup
3

More than 1 year has passed since last update.

posted at

updated at

webページをPythonとSeleniumで自動入力する

あるページに定期的に情報を入力する機会があったのでこれを自動化しました

下準備

環境

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と入力し表示されるリモートデスクトップ接続を起動する
image.png

コンピューター名にインスタンスのアドレスを入力する
image.png

接続先がwindowsではなくLinuxなので警告が表示されるが、意図した用途のためはいを選択し続行する

ログイン画面が表示されるため、ユーザー名にubuntu、パスワードは先程設定したものを入力する。
image.png

以下のような初期設定画面が表示される。キーボードやプライバシーの設定があるが、リモートアクセスのためそのまま次へを選択してよい。
image.png

ソフトウェアアップデーターからアップデートの通知が来る場合があるが、内容を確認しセキュリティーアップデートで無い限りはアップデートは行わないことにする。
image.png

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をクリックする。
image.png

以下の画面が表示される。今回はイチから作成するためCreate a new projectを選択する。
image.png

プロジェクトの名前を付ける。特に指定はないが、今回はsample_project1とする。
image.png

Selenium IDEのホーム画面が表示される。
操作の記録を開始するため、右上のRECボタンを選択する
image.png

プロジェクトのURLを入力する。先程のデモサイトを利用する場合はhttp://example.selenium.jp/reserveApp_Renewal/と入力する。
image.png

対象ページが表示される。自動化したい操作を最後まで入力する。
image.png

操作が完了したら起動したタブを閉じる。Selenium IDEの画面に戻るので、先程選択した右上のRECボタンのところにある■をクリックする。
image.png

するとTEST NAMEを入力する画面になる。これは今回の一連の操作に名前をつけてね、ということだ。
今回はoperation1としておく。これも特に指定はないので自由に入力して問題ないが、わかりやすくするために先程のプロジェクト名とは別のものにしておくことが無難だろう。
image.png

今回記録した内容は、このSelenium IDEを閉じると消えてしまうためファイルに保存する。
右上の保存ボタンをクリックする。
image.png

保存場所とファイル名を確認し、プロジェクトファイルを保存する。
プロジェクトファイルは複数テストケースを作成した場合でも、そのプロジェクト全体で保存し、次に読みだした場合はそのテストケースすべてが読み込まれる。
なお、この保存はwindowsならCtrl+Sでも可能だ。
image.png

保存が完了したので、試しに今記録した動作が問題なく実行できるか確認してみる。
Selenium IDEの上部真ん中あたりの三角の再生ボタンをクリックし実行する。
実行ボタンは2つ並んでいるが、左の実行ボタンはプロジェクトに保存されているすべてのテストケースを実行、右の実行ボタンは選択しているテストケースのみを実行する。今回は右の実行ボタンを選択する。
image.png

もし途中で意図しない動作を行った場合はここで修正しておく。

今回作成したテストケースはSelenium IDEから実行することを想定しているため、Pythonに変換する。
Selenium IDE左上の表示がTestsになっていることを確認し、該当するテストケースにマウスカーソルを合わせるとが表示される。これを右クリックする
image.png

Exportを選択する。
image.png

Pythonを選択し、表示を見やすくするために上から2つのチェックボックスを選択しEXPORTを選択する
image.png

保存場所とファイル名を確認し保存する。
image.png

なお、ここで生成されるコードはそのままでは使えないので修正する必要がある。

生成直後の素のコード↓
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

以下実行例のスクショ
image.png

これを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のプログラムを自動実行する必要がある。

autofill.sh
#!/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

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
What you can do with signing up
3