こんばんは、@0yanです。
課メンバーに業務自動化要望をヒアリングしたら、「Webアプリの手作業を自動化して欲しい」という要望があった為、Seleniumで自動化ツールを作成、PyInstallerで実行ファイルにして配布しました。
その際、学びがあったのでこちらで紹介したいと思います。
想定している読者
- Python+Seleniumで業務自動化しているノンプログラマーや初心者の方
- コード読めない方から「Webアプリの自動化ツールを作って欲しい」と要望受けている方
コンテンツ
- PyInstaller超便利
- Seleniumのfind_element_by_css_selector超便利
- おまけ:Seleniumで躓きがちなこと
環境
- Windows10
- Python 3.7.3(Anaconda3)
PyInstaller超便利
自動化ツール依頼元のメンバーがプログラミング未経験者のため、「環境構築だけで一苦労だろうな・・・どうにか良い方法ないだろうか」と探しておりました。
ありました。
実行ファイル形式で配布するという方法が。
使い方の前に注意事項
普段、Seleniumを使った自動化をする際は、chromedriver-binaryを使った方がラクなので、そうしている方が多いと思います。
が!Seleniumを使ったコードを実行ファイル形式にして配布しても、Chrome Driverが無ければ動きません。
- Chrome Driverは実行ファイル形式を使うこと前提でコーディングする
- 実行ファイルとセットでChrome DriverのダウンロードURLも共有、適切なドライバーをダウンロードするよう伝える
- Chrome Driverの実行ファイルは指定のパスに格納することを伝達する
- 配布先のPCのデスクトップパス等は、
os.environ.get()
を使って取得するようにする - ログインIDやパスワードの入力を求める際は、input関数を使って最初に求めるようにする
といった配慮が必要です。
PyInstallerの使い方
-
pip install pyinstaller
コマンドでPyInstallerをインストール -
pyinstaller ファイル名.py --onefile
コマンドを打ち、実行ファイルを作成 - distディレクトリに実行ファイルができるので配布する
以上、3stepです。
めっちゃ簡単!
Seleniumのfind_element_by_css_selector超便利
今まで、Seleniumで要素を探す際、
- find_element_by_id
- find_element_by_name
- find_element_by_class_name
- find_element_by_tag_name
- find_element_by_link_text
- find_element_by_partial_link_text
でダメだったら「詰んだ・・・最後の手段だ!」とfind_element_by_xpathメソッドを使っておりましたが、find_element_by_css_selectorメソッドを使えば解決できるということを知りました。
※ここから先、find_element_by_
は~
で省略させて頂きます。
使い方①:クラス名の中に空白があっても大丈夫!
HTMLタグ内のクラス名が「class=test hogehoge」となっている場合、~class_nameメソッドでは対応できませんが、**~css_selector(.test.hogehoge)**とすることで要素取得できます。
使い方②:クラス名が重複してても大丈夫!
例えば、hogehogeというクラス名のHTMLタグが複数あった場合、find_elements_by_class_nameメソッドでそれらをすべて取得、for文で一つずつ目的の要素か否か調べることもできますが、~css_selectorメソッドの引数をタグ名.クラス名やタグ名#ID名.クラス名とすることでユニークになれば、for文まわさなくてもいけます。
【具体例1:下記タグが同じページに存在する場合】
1) <select class=hogehoge>
2) <input class=hogehoge>
3) <input id=123 class=hogehoge>
4) <input class=hogehoge name=789>
≪要素取得方法≫
1) find_element_by_css_selector('select.hogehoge')
2) find_element_by_css_selector('input.hogehoge')
3) find_element_by_css_selector('input#123.hogehoge')
4) find_element_by_css_selector('input.hogehoge[name="789"])
【具体例2:divの属性が異なるが、その直下のタグのクラス名や属性がまったく同じ場合】
1) <div class="pb-edit" data-id="1628">の子の<select>タグ
2) <div class="pb-edit" data-id="1629">の子の<select>タグ
≪要素取得方法≫
1) driver.find_element_by_css_selector('div[data-id="1628"] > select)
2) driver.find_element_by_css_selector('div[data-id="1629"] > select)
【具体例3:定期的にクラス名が変わって困る場合】
≪タグ≫
<button placeholder="メンバーを検索" value="" class="Button__DefaultButton-ouh7gw-1 Button__PrimaryButton-ouh7gw-2 SearchBox__SearchButton-sc-1riae5a-1 bHQZyE Button__PrimaryMediumButton-ouh7gw-4 cFhiOs">
≪要素取得方法≫
下記の通り、~css_selector('タグ名[属性名="値"]')でいける。
find_element_by_css_selector('button[placeholder="メンバーを検索"]')
多分、普段CSSを触っている方からしたら「こんな簡単なことも知らんのかい!」と言われるような内容かもしれません。
が、私のようにノンプログラマーでCSSと縁がない人間でも便利に使えるのがPythonの良さだと思いますし、そういう方もいると思いますのでここで共有させて頂きました。
おまけ:Seleniumで躓きがちなこと
ファイルアップロードとスクロールで躓きがちだと思います。
知っている方もいるかと思いますが、こちらで紹介させて頂きます。
ファイルアップロード
Send_keysでできます。
スクロール
画面に表示されていない要素は取得できないため、スクロールしたいこともあると思います。
下記のとおり、ActionChainsクラスを使うことでスクロールできます。
element = driver.find_element_by_id('hogehoge')
action = ActionChains(driver)
action.move_to_element(element)
action.perform()
さいごに
長文にも関わらず、ご覧頂き誠にありがとうございました!
もし、間違い等がございましたらご指摘頂けますと幸いです。
宜しくお願い致しますm(_ _)m
参考サイト
PythonスクリプトをWindows環境で動くexeファイルにしよう!
コマンドプロンプト/Windowsの主要な環境変数一覧と意味
【初心者向け】CSSセレクタとは?セレクタの種類や指定方法を解説!(基礎編)
セレクタの種類
Python3 selenium ローカルファイル選択