seleniumの使い方を具体例と共に解説【Python】

概要

seleniumで要素が取得できないといった疑問を解決するために、色々苦戦した結果編み出した、使い方と使用例を紹介していきたいと思います。

seleniumは結構便利ですが、整理されていないと要素が取得できないことが多くかなり使いずらくなりますよね。。。
例えば、ネットワーク遅延などで要素の表示が遅れるとすぐにエラーになったりします。

今回はそんな開発現場でよくある厄介な問題を解決できるようなメソッドをクラスまとめてみました。

初心者の方にもチートシートとして使用できるようにまとめてみたのでよければ見ていってください。

それではやっていきましょう!

目次

ソースコード全体

説明しやすいので先にクラスの全体を書きます。

ここにあるソースコードを一つずつ紹介していきます。

seleniumのクラス

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.select import Select
from selenium.webdriver.chrome.service import Service as ChromeService

class MySelenium:
driver=None
url=""

# classの初期化
def __init__(self,url):
self.url=url
self.get()

# urlの画面を開く
def get(self):
#不要なブラウザ制御コメントを非表示にする
ChromeOptions = webdriver.ChromeOptions()
ChromeOptions.add_experimental_option('excludeSwitches', ['enable-logging'])
#driverオブジェクト作成
self.driver=webdriver.Chrome(options=ChromeOptions)
self.driver.get(self.url)

# フォームに文字を入力
def sendKeys(self,type,name,key):
element = self.getWaitElement(type,name)
element.send_keys(key)

# フォームをクリア
def clearKeys(self,type,name):
element = self.getWaitElement(type,name)
element.clear()

# ボタン押下
def clickButton(self,type,name):
element = self.getClickElementWait(type, name)
element.click()

# 要素のテキストを取得
def getElementText(self,type,name):
element = self.getWaitElement(type,name)
return element.text

# 複数要素を取得する
def getWaitElements(self,type,name):
wait = WebDriverWait(self.driver, 20)
el = wait.until(expected_conditions.visibility_of_all_elements_located((type,name)))
return el

# 要素を取得する
def getWaitElement(self,type,name):
wait = WebDriverWait(self.driver, 20)
el = wait.until(expected_conditions.visibility_of_element_located((type,name)))
return el

# 要素取得し押下する
def getClickElementWait(self,type,name):
wait = WebDriverWait(self.driver, 20)
return wait.until(expected_conditions.element_to_be_clickable((type,name)))

# 画面を閉じる
def quit(self):
self.driver.quit()

# 画面をリセット
def reset(self):
self.quit()
self.get()

説明

初期化処理(__init__)

seleniumのクラスの初期化処理です。

引数で指定したURLで画面を開く処理をしています。

__init__

1
2
3
4
# classの初期化
def __init__(self,url):
self.url=url
self.get()

呼び出し例

1
driver = Selenium('https://www.hoge.com/test/')
上記の例では「**https://www.hoge.com/test**」というサイトがクラスにセットされ、画面が起動します。
  • 引数(url)
    • seleniumで操作したいURLを指定

urlの画面を開く(get)

classに設定されているURLの画面を開きます。

init処理でも使用しており、基本的に当クラス内でのみ呼び出すメソッドであり、直接使用することはほぼないと思います。

内部では「add_experimental_option」を使用しており、selenium起動時にchromeの上に表示されるバーを消して、seleniumのgetメソッドで画面を開いています。

get

1
2
3
4
5
6
7
8
# urlの画面を開く
def get(self):
#不要なブラウザ制御コメントを非表示化しています
ChromeOptions = webdriver.ChromeOptions()
ChromeOptions.add_experimental_option('excludeSwitches', ['enable-logging'])
#driverオブジェクト作成
self.driver=webdriver.Chrome(options=ChromeOptions)
self.driver.get(self.url)

呼び出し例

1
driver.get()

フォームに文字を入力(sendKeys)

引数で指定したフォームに文字を入力します。
フォームのinput要素などにこのメソッドを使えば簡単に文字を入れることができます。

内部的にはページ下部で紹介している「getWaitElement」を呼び出し要素を取得、
seleniumの「send_keys」メソッドで文字を入力しています。

sendKeys

1
2
3
4
# フォームに文字を入力
def sendKeys(self,type,name,key):
element = self.getWaitElement(type,name)
element.send_keys(key)

呼び出し例

1
driver.sendKeys(By.XPATH,"/html/body/form/input",'ほげほげ')
上記の例ではXPASSの「/html/body/form/input」に「ほげほげ」という文言が入ります。
  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.ID:要素のID
    •  By.NAME:inputに指定されるNAME
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ
  • 引数(key)
    • 要素に入力したい文字列

フォームの文字をクリア(clearKeys)

フォームの文字をクリアします。

内部的にはページ下部で紹介している「getWaitElement」を呼び出し要素を取得、
seleniumのclearメソッドを呼び出して要素をクリアしています。

clearKeys

1
2
3
4
# フォームをクリア
def clearKeys(self,type,name):
element = self.getWaitElement(type,name)
element.clear()

呼び出し例

1
driver.clearKeys(By.XPATH,"/html/body/form/input")
上記の例では、XPASS「/html/body/form/input」の要素にある文字列がクリアされます。
  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.ID:要素のID
    •  By.NAME:inputに指定されるNAME
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ

ボタン押下(clickButton)

指定された要素のボタンを押下します。

内部的にはページ下部で紹介している「getClickElementWait」を呼び出し要素を取得、
seleniumのclickメソッドを呼び出してボタンを押下しています

clickButton

1
2
3
4
# ボタン押下
def clickButton(self,type,name):
element = self.getClickElementWait(type, name)
element.click()

呼び出し例

1
driver.clickButton(By.ID,"ACCEPT")

上記の例ではIDが「ACCEPT」という要素が押下されます。

  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.ID:要素のID
    •  By.NAME:inputに指定されるNAME
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ

要素のテキストを取得(getElementText)

要素に書かれているテキストを取得します。

内部的にはページ下部で紹介している「getWaitElement」を呼び出し要素を取得、
seleniumのtext変数からテキストを取得しています。

getElementText

1
2
3
4
# 要素のテキストを取得
def getElementText(self,type,name):
element = self.getWaitElement(type,name)
return element.text

呼び出し例

1
test = driver.getElementText(By.ID,"COMMENT")
上記の例だと、IDが「COMMENT」の要素に「アメンボ」と書かれていた場合、 変数「test」に「アメンボ」という文字列が入ります。
  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.ID:要素のID
    •  By.NAME:inputに指定されるNAME
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ

要素を複数取得(getWaitElements)

要素を複数要素を取得します。

例えば、特定のclassの要素を取得して、順番に文字を入れたい場合などに使用できます。
上で紹介したメソッドではカバーしきれない複雑な処理などに対応するために、作成しております。

実際自分の場合だと、入力フォームのinputをすべて取得して、それぞれに同じ値を入れたいときに使用しています。

内部的にはseleniumの「expected_conditions.visibility_of_all_elements_located」を使用して、要素が取得可能になったら、要素を取得するようにしています。

getWaitElements

1
2
3
4
5
# 複数要素を取得する
def getWaitElements(self,type,name):
wait = WebDriverWait(self.driver, 20)
el = wait.until(expected_conditions.visibility_of_all_elements_located((type,name)))
return el

呼び出し例

1
2
3
4
el_input=driver.getWaitElements(By.CLASS,'comment')
#要素分だけループ
for i in range(len(el_input)-1):

上記の例だと、classが「comment」の要素をすべて取得し、その要素をループして処理しています。
  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.CLASS_NAME:要素のclass
    •  By.TAG_NAME:HTMLのタグ(P要素など)
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ

要素を取得(getWaitElement)

引数で指定した要素を取得します。

基本的には当クラス内で呼び出すものですが、メソッドにない機能や複雑な処理を行いたい場合に使用します。

内部的にはseleniumの「expected_conditions.visibility_of_element_located」を使用して、要素が取得可能になったら、要素を取得するようにしています。

getWaitElement

1
2
3
4
5
# 要素を取得する
def getWaitElement(self,type,name):
wait = WebDriverWait(self.driver, 20)
el = wait.until(expected_conditions.visibility_of_element_located((type,name)))
return el

呼び出し例

1
el = driver.getWaitElement(By.ID,'USER_NAME')

上記の例だと、idが「USER_NAME」の要素を取得します。

  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.ID:要素のID
    •  By.NAME:inputに指定されるNAME
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ

クリック可能な要素を取得(getClickElementWait)

クリック可能な要素を取得します。

基本的には、当クラス内の「clickButton」メソッドで使用するものです。

とはいえ特定のボタンが押下可能な状態かどうかを判定する処理などにも使えると思うので、一応紹介します。

内部的にはseleniumの「expected_conditions.element_to_be_clickable」を使用して、要素が押下可能になったら、要素を取得するようにしています。

getClickElementWait

1
2
3
4
5
# 要素取得し押下する
def getClickElementWait(self,type,name):
wait = WebDriverWait(self.driver, 20)
return wait.until(expected_conditions.element_to_be_clickable((type,name)))

呼び出し例

1
el_btn=driver.getClickElementWait(By.ID,'ACCEPT_BUTTON')

上記の例だと、id「ACCEPT_BUTTON」の要素が押下可能ならば取得します。

  • 引数(type)
    • セレクタの種類
    • Byクラスを使用すること
    • 例)
    •  By.ID:要素のID
    •  By.NAME:inputに指定されるNAME
    •  By.XPATH:要素のXPASS
  • 引数(name)
    • typeで指定した種類のセレクタ

画面を閉じる(quit)

seleniumでの操作が完了したら呼び出す処理です。

これをやらないと無駄にメモリを圧迫するので、処理の最後に必ずやっておきましょう!

内部的にはseleniumの「quit」を呼び出してドライバを閉じています。

quit

1
2
3
4
# 画面を閉じる
def quit(self):
self.driver.quit()

呼び出し例

1
driver.quit()

画面を再表示する(reset)

画面を一度閉じて、再表示するときに使用します。

入力完了後、画面をリセットしてまた入力しなおしたいときなどに使用します。

内部的には当メソッド内の「quit」と「get」メソッドを呼び出して画面の再表示を実装しています。

reset

1
2
3
4
# 画面をリセット
def reset(self):
self.quit()
self.get()

呼び出し例

1
driver.reset()

締め

こんな感じで、seleniumのクラスを作ってみました。

純粋なseleniumと比べるとかなり使いやすくなったのではないでしょうか?
個人的には要素が表示されるのを自動で待ってくれる機能がお気に入りです。

開発現場ではかなり苦しめられましたから、、、

もし皆様の助けになれたらうれしいです!

こんな感じで自分のブログではエンジニアとしてやってきたことをメモレベルで残しています。
他の記事もよければ見ていってください!

以上
ナレッジの共有は必須事項ですよ!仕事を休むためにも!
お疲れさまでした。