Selenium&pythonの組合せで、Webアプリケーションを自動化して使う「個人的なTips」3回シリーズの2回目です。
今回は何かをクリックする行為に関わる部分です。
記事の前提と留意点
自分がよく使うケースをまとめています。
似たような使い方をする誰かの参考になれば・・のスタンスです。
長くなるので、3回にわけていて、今回はその2回目です。
- 1回目:入力したり、選択したりのTipsあれこれ
- 2回目:何かをクリックする場合のTipsあれこれ(今回)
- 3回目:Webアプリの値を参照したり、スクロールしたり他Tips(9/26木曜日公開予定)
主な内容は。
- Seleniumのclick()を使ったボタンのクリック
- ボタンが押せない時にonClick()のJavaScriptを直接実行する
- チェックボックス・ラジオボタンのクリック(単独・グループ)
- チェックボックス・ラジオボタンの上の要素をJavaScriptでクリック
- グループ化でnameが同じチェックボックス・ラジオボタンのクリック
- リンクのクリック
です。
ソースのサンプルは、クラスの部品としてメソッドを定義するように書いてます。
その使い方は、末尾の方にかいてます。
なお、MyRpaToolsクラス全体のソースコードは3回目の末尾に掲載する予定です。
さて。
内容にはいります。
個別のクリック部品群
Seleniumで自動処理する各ケースごとにまとめます。
Seleniumのclick()を使ったボタンのクリック
typeが「submit」であるボタンと、「button」であるボタンがあります。
<input type="submit" id="sname" class="sname" name="sname" value="サブミット"> <input type="button" id="bname" class="bname" name="bname" value="ボタン">
それをちゃんと区別して使うSeleniumっぽいやつです。
def click_submit(self, name): element = self.driver.find_element_by_xpath( "//input[@name='" + name + "'][@type='submit']") element.click() def click_button(self, name): self.driver.find_element_by_xpath( "//input[@type='button'][@name='" + name + "']").click()
上がSubmit、下がbuttonです。
Selenium共通の制約で、画面から隠れているボタンをclick()するとエラーになります。
ボタンが押せない時にonClick()のJavaScriptを直接実行する
画面から隠れているボタンを押してもエラーにしたくない場合は、onClickで紐づいているJavaScriptを直接実行する方法が有効です。
def execute_script(self, scr): self.driver.execute_script(scr)
Seleniumのexcute_scriptを単純にラップしているだけですけど、便利です。
例えば。
<input type="button" onclick="script_test();">
みたいなものがあれば、
auto.execute_script("script_test();")
みたいに、クリックされたとみなして、JavaScriptを実行します。
チェックボックス・ラジオボタンのクリック(単純版)
typeがcheckboxになったり、radioになったりするだけです。
def click_checkbox(self, name): self.driver.find_element_by_xpath( "//input[@type='checkbox'][@name='" + name + "']").click() def click_radio(self, name): self.driver.find_element_by_xpath( "//input[@type='radio'][@name='" + name + "']").click()
でも。
こんなシンプルなケースは今時、ほとんどありません。
チェックボックス・ラジオボタンの上の要素をJavaScriptでクリック
チェックボックスやラジオボタンそのものをCSSで「displey:none」にして、画像やlabelをかぶせているようなケースです。
例えばこんな感じ。
<label name="inner_chk">
<input type="checkbox" name="inner_chk">チェックする場所
</label>
こんな時は、上の<label>の部分をクリックする必要があります。
ところが、Seleniumの機能を使ってClick()しようとすると、labelがclickable(クリック可能)ではないなどとエラーがでてうまくいきません。
そんな時には、JavaScriptの機能で直接click()します。
def click_by_name(self, name): self.driver.execute_script( "document.getElementsByName('" + name + "')[0].click();")
これだと、labelもクリックできます。
グループ化でnameが同じチェックボックス・ラジオボタンのクリック
radioボタンをグループ化して、nameには同じ名前・・たとえば「radio_group_xxx」みたいな・・を設定している場合があります。
その場合は、同じ名前の複数のエレメントを取得して、その何番目(index)をクリックするという方を使います。
def click_by_names(self, name, index): self.driver.execute_script( "document.getElementsByName('" + name + "')[" + index + "].click();")
例えば。
ラジオボタンがグループされて、3つ並んでいる場合とかだと。
auto.click_by_names('radio_group_xxx', '1')
time.sleep(1)
auto.click_by_names('radio_group_xxx', '2')
time.sleep(1)
auto.click_by_names('radio_group_xxx', '3')
みたいにして、1秒おきに、上から順番にチェックする・・とかして、連動して表示が変わる部分の動作をテストで確認するみたいに使ってます。
リンクのクリック
これはとてもシンプルです。
一番楽なのは、リンクのテキストで識別してクリックするもの。
def click_link_by_text(self, text): element = self.driver.find_element_by_link_text(text) element.click()
例えば、「auto.click_link_by_text("カヨコ")」みたいな感じです。
テキスト表示のリンクはこれでいけます。
ただ、テキストがなくて、画像に直接リンクをはったりしている場合もあるので、そういうときは、以下みたいにtitle属性に着目してみたり・・して、都度対応する必要があります。
def click_link_titled(self, name): element = self.driver.find_element_by_xpath("//a[@title='" + name + "']") element.click()
xpathの指定の仕方に慣れれば、たいてい対応できます。
でも。
どうしても、識別する方法が見つからない場合には、<a>タグを全部ひろって、何番目のリンクをクリックする・・みたいな手も使います。
def click_link_by_index(self, index): self.driver.execute_script("document.getElementsByTagName('a')[" + str(index) + "].click();")
これの使い方は。
auto.click_by_index(2)
とかして、HTMLの2番目のリンクをクリックします。
テキストなしに上部に画像を<a>タグで囲んだものが並んでいるアクションパネルもどきみたいなものがあるときには便利だったりします。
使い方のイメージとか
Seleniumをダイレクトに書くとゴチャゴチャして、読みづらくなります。
そのため、MyRpaToolsというクラスに部品をまとめて、操作の流れにあわせて、1行ずつペタペタ部品を貼り付けていくような使い方をしています。
使い方のイメージはこうです。
import my_rpa_tools as my from selenium import webdriver import time # Edge WebDriver initial setting driver = webdriver.Edge( executable_path='C:\\windows\\system32\\MicrosoftWebDriver.exe') driver.get('https://coopweb.itecs.local/pro_staff/ps_login.php') auto = my.MyRpaTools(driver) # login auto.input_text('login_id', 'user0001')
上記例だと、Edgeドライバーを、「driver」という名前のオブジェクトにセットして、それを引数に「MyRpaTools」クラスインスタンスを生成してます。
上記ではその名前を「auto」にしていて、あとは、「auto.input_text」のように、クラスで定義したメソッドを並べていく感じです。
二回目まとめ
今回は、クリックでした。
このテーマでは3回にわけてやっています。
1回目と3回目はこちらです。
1回目
3回目
seleniumのインストールやWEBドライバの取得等については、こちらの記事にまとめてます。
今回はこんなところで。
ではでは。