![見出し画像](https://assets.st-note.com/production/uploads/images/45602075/rectangle_large_type_2_20a1903bd56904c7e74d3b071b751625.png?width=1200)
Le Selenium avec P02:elementをみつける
【0】はじめに
今回はSeleniumをつかって、「HTML内の要素(element)」をみつける操作までを実施する。
人間がブラウザを操作する時は、まず自分の目で「入力エリア」や「ボタン」の位置を確認して、次にフォーカスを当てて、「キー入力操作」や「クリック操作」をしている。
同じことをプログラム(Selenium)上で実行するためには、まず最初にHTMLドキュメント内から要素(element)をプログラムで検出する。
検出した「要素(element)」は、「WebElementオブジェクト」として属性値(htmlタグの設定内容)を取得する、クリック処理する、といった操作をプログラミングできる。
【1】find_element_by_〇〇〇でelementを見つける
■ブラウザを起動してHTMLの構造を確認する
Seleniumで「要素(element)」を見つけるにあたって、まずはブラウザを起動して対象のページのHTML構造を確認する。
■WebDriver.find_element_by_〇〇〇メソッド
Seleniumでは「find_element_by_〇〇〇メソッド」を使ってHTML内の要素(element)検出することができる。
使用できるメソッドは次の通り。
・find_element_by_id(id)
・find_element_by_name(name)
・find_element_by_class_name(name)
・find_element_by_tag_name(name)
・find_element_by_xpath(xpath)
・find_element_by_css_selector(css_selector)
・find_element_by_link_text(link_text)
・find_element_by_partial_link_text(link_text)
「find_elements_by_〇〇」のように「s」をつけると該当するelementを複数取得できる。
例1:「Usernameのテキストエリア」を「name属性で検出する」
検出した「WebElementオブジェクト」から、そのelement内の別の属性値を取得することもできる。
■例2:検出したelement内にあるsize属性の値を取得する
from selenium import webdriver
import chromedriver_binary # pipでいれたのでこれが必要
driver = webdriver.Chrome()
# 10秒の暗黙ウェイト
driver.implicitly_wait(10)
driver.get('http://localhost:8080/login.php')
# name で探したelementから別の属性値を取得
username_field = driver.find_element_by_name("username")
print(username_field.get_attribute("size"))
出力結果:
20
■例3:find_elements_by_tag_nameで複数要素を取得する「find_elements_by_〇〇」のように「s」をつけて複数要素を取得してみる。今回は「各inputタグのelement」を取得して「それぞれname属性」を出力してみる。
input_fields = driver.find_elements_by_tag_name('input')
for el in input_fields:
print(el.get_attribute("name"))
出力結果:
username
password
Login
user_token
【2】XPathを使う
Seleniumでelementを一意に特定するにはちょうどいいid属性やname属性がない場合、XPathを使って検索することもできる。XPathはXML文書(HTML含む)のノードを検索するためのクエリー言語。
■使い方:XPathの取得の仕方
ブラウザからコピー操作をすればよい。XPathには「絶対パス」と「相対パス」があるが相対パスを使う方が便利。
例えば「Password欄のXPath」は以下のようなものが取得できる
# 相対パスのXPath
//*[@id="content"]/form/fieldset/input[2]
# 絶対パスのXPath
/html/body/div/div[2]/form/fieldset/input[2]
あとは「find_element_by_xpath()」で取得すればよい。
■例4:Password欄のname属性を取得する
password_fields = driver.find_element_by_xpath('//*[@id="content"]/form/fieldset/input[2]')
print(password_fields.get_attribute("name"))
出力結果:
password
【3】ここまでの全体コード
name属性での取得、tag名での複数取得、XPathでの取得についてまとめた全体コードは以下のような感じ。
from selenium import webdriver
import chromedriver_binary # pipでいれたのでこれが必要
driver = webdriver.Chrome()
# 10秒の暗黙ウェイト
driver.implicitly_wait(10)
driver.get('http://localhost:8080/login.php')
# name 要素から探す
username_field = driver.find_element_by_name("username")
print(username_field.get_attribute("size"))
# inputタグをすべて探してname要素の値を出力する
input_fields = driver.find_elements_by_tag_name('input')
for el in input_fields:
print(el.get_attribute("name"))
print("--------")
# xpathで指定する
password_fields = driver.find_element_by_xpath('//*[@id="content"]/form/fieldset/input[2]')
print(password_fields.get_attribute("name"))
driver.quit()
出力結果:
20
username
password
Login
user_token
--------
password
【おまけ】要素を検出できなかった場合の例外エラー:NoSuchElementException
Seleniumでは「find_element_by_〇〇〇」で一致する要素が見つけられなかった場合、「NoSuchElementException」という「例外」を発出する。
そのため、try-exceptで例外を捕捉して何らかの処理をする、といったこともできる。(例えば、Webアプリの自動テストで例外が発生した時点で画面キャプチャする、等)
■例:例外を検知して終了する
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
... ...
try:
email_field = driver.find_element_by_name("email")
except NoSuchElementException:
print("can not find element")
#driver.save_screenshot("error.png")
#raise
driver.quit()
いいなと思ったら応援しよう!
![fz5050](https://assets.st-note.com/production/uploads/images/33869673/profile_56684e35407d563dbeb38e0a193976a0.png?width=600&crop=1:1,smart)