ウェブ要素の検出
Selenium を使用する上で最も基本的な側面の一つは、操作する要素の参照を取得することです。Selenium は、要素を一意に識別するための組み込みのロケータ戦略を多数提供しています。ロケータを高度なシナリオで使用する方法はたくさんあります。このドキュメントの目的のために、次の HTML スニペットを考えてみましょう。
<ol id="vegetables">
<li class="potatoes">…
<li class="onions">…
<li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
<li class="bananas">…
<li class="apples">…
<li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
最初に一致する要素
多くのロケータは、ページ上の複数の要素に一致します。単数要素検索メソッドは、特定のコンテキスト内で最初に見つかった要素への参照を返します。
DOM 全体の評価
要素検索メソッドがドライバインスタンスで呼び出されると、提供されたロケータに一致する DOM 内の最初の要素への参照が返されます。この値は保存して、将来の要素アクションに使用できます。上記の HTML 例では、クラス名が「tomatoes」の要素が 2 つあるため、このメソッドは「vegetables」リスト内の要素を返します。
WebElement vegetable = driver.findElement(By.className("tomatoes"));
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
fruits = driver.find_element(id: 'fruits')
fruit = fruits.find_element(class: 'tomatoes')
const vegetable = await driver.findElement(By.className('tomatoes'));
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
DOM のサブセットの評価
DOM 全体で一意のロケータを見つけるのではなく、検索範囲を別の特定された要素のスコープに絞り込むと便利な場合があります。上記の例では、クラス名が「tomatoes」の要素が 2 つあり、2 番目の要素の参照を取得するのは少し困難です。
1 つの解決策は、目的の要素の祖先であり、不要な要素の祖先ではない一意の属性を持つ要素を特定し、そのオブジェクトに対して要素検索を呼び出すことです。
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
fruits = driver.find_element(id: 'fruits')
fruit = fruits.find_element(class: 'tomatoes')
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
Java および C#WebDriver
、WebElement
、および ShadowRoot
クラスはすべて、ロールベースインターフェースと見なされる SearchContext
インターフェースを実装しています。ロールベースインターフェースを使用すると、特定のドライバ実装が特定の機能をサポートしているかどうかを判断できます。これらのインターフェースは明確に定義されており、単一の責任ロールのみを持つように努めています。
Shadow DOM の評価
Shadow DOM は、要素内に隠されたカプセル化された DOM ツリーです。Chromium ブラウザの v96 のリリースにより、Selenium は使いやすいシャドウルートメソッドを使用してこのツリーにアクセスできるようになりました。注: これらのメソッドには Selenium 4.0 以上が必要です。
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
最適化されたロケータ
ネストされたルックアップは、ブラウザに 2 つの別々のコマンドを発行する必要があるため、最も効果的なロケーション戦略ではない可能性があります。
パフォーマンスをわずかに向上させるために、CSS または XPath のいずれかを使用して、単一のコマンドでこの要素を見つけることができます。 ロケータ戦略の提案については、推奨されるテストプラクティスセクションを参照してください。
この例では、CSS セレクタを使用します。
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
fruit = driver.find_element(css: '#fruits .tomatoes')
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
すべての一致する要素
最初の一致要素だけでなく、ロケータに一致するすべての要素への参照を取得する必要があるユースケースがいくつかあります。複数要素検索メソッドは、要素参照のコレクションを返します。一致するものがない場合は、空のリストが返されます。この場合、すべての果物と野菜のリスト項目の参照がコレクションで返されます。
List<WebElement> plants = driver.findElements(By.tagName("li"));
plants = driver.find_elements(By.TAG_NAME, "li")
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
plants = driver.find_elements(tag_name: 'li')
const plants = await driver.findElements(By.tagName('li'));
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
要素の取得
多くの場合、要素のコレクションを取得しますが、特定の要素を操作したい場合があります。つまり、コレクションを反復処理して、目的の要素を特定する必要があります。
List<WebElement> elements = driver.findElements(By.tagName("li"));
for (WebElement element : elements) {
System.out.println("Paragraph text:" + element.getText());
}
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
# Navigate to Url
driver.get("https://www.example.com")
# Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')
for e in elements:
print(e.text)
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;
namespace FindElementsExample {
class FindElementsExample {
public static void Main(string[] args) {
IWebDriver driver = new FirefoxDriver();
try {
// Navigate to Url
driver.Navigate().GoToUrl("https://example.com");
// Get all the elements available with tag name 'p'
IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
foreach(IWebElement e in elements) {
System.Console.WriteLine(e.Text);
}
} finally {
driver.Quit();
}
}
}
}
elements = driver.find_elements(:tag_name,'p')
elements.each { |e| puts e.text }
const {Builder, By} = require('selenium-webdriver');
(async function example() {
let driver = await new Builder().forBrowser('firefox').build();
try {
// Navigate to Url
await driver.get('https://www.example.com');
// Get all the elements available with tag 'p'
let elements = await driver.findElements(By.css('p'));
for(let e of elements) {
console.log(await e.getText());
}
}
finally {
await driver.quit();
}
})();
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver
fun main() {
val driver = FirefoxDriver()
try {
driver.get("https://example.com")
// Get all the elements available with tag name 'p'
val elements = driver.findElements(By.tagName("p"))
for (element in elements) {
println("Paragraph text:" + element.text)
}
} finally {
driver.quit()
}
}
要素から要素を検索
これは、親要素のコンテキスト内で一致する子 WebElement のリストを見つけるために使用されます。これを実現するには、親 WebElement を 'findElements' とチェーンして、子要素にアクセスします。
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
public class findElementsFromElement {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
// Get element with tag name 'div'
WebElement element = driver.findElement(By.tagName("div"));
// Get all the elements available with tag name 'p'
List<WebElement> elements = element.findElements(By.tagName("p"));
for (WebElement e : elements) {
System.out.println(e.getText());
}
} finally {
driver.quit();
}
}
}
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME
# Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')
# Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
print(e.text)
##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path
# Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')
# get children of tag 'ul' with tag 'li'
elements = driver.find_elements(By.XPATH, './/li')
for e in elements:
print(e.text)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;
namespace FindElementsFromElement {
class FindElementsFromElement {
public static void Main(string[] args) {
IWebDriver driver = new ChromeDriver();
try {
driver.Navigate().GoToUrl("https://example.com");
// Get element with tag name 'div'
IWebElement element = driver.FindElement(By.TagName("div"));
// Get all the elements available with tag name 'p'
IList < IWebElement > elements = element.FindElements(By.TagName("p"));
foreach(IWebElement e in elements) {
System.Console.WriteLine(e.Text);
}
} finally {
driver.Quit();
}
}
}
}
element = driver.find_element(:tag_name,'div')
elements = element.find_elements(:tag_name,'p')
elements.each { |e| puts e.text }
const {Builder, By} = require('selenium-webdriver');
(async function example() {
let driver = new Builder()
.forBrowser('chrome')
.build();
await driver.get('https://www.example.com');
// Get element with tag name 'div'
let element = driver.findElement(By.css("div"));
// Get all the elements available with tag name 'p'
let elements = await element.findElements(By.css("p"));
for(let e of elements) {
console.log(await e.getText());
}
})();
import org.openqa.selenium.By
import org.openqa.selenium.chrome.ChromeDriver
fun main() {
val driver = ChromeDriver()
try {
driver.get("https://example.com")
// Get element with tag name 'div'
val element = driver.findElement(By.tagName("div"))
// Get all the elements available with tag name 'p'
val elements = element.findElements(By.tagName("p"))
for (e in elements) {
println(e.text)
}
} finally {
driver.quit()
}
}
アクティブな要素を取得
これは、現在のブラウジングコンテキストでフォーカスがある DOM 要素を追跡(または)見つけるために使用されます。
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
public class activeElementTest {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
try {
driver.get("http://www.google.com");
driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");
// Get attribute of current active element
String attr = driver.switchTo().activeElement().getAttribute("title");
System.out.println(attr);
} finally {
driver.quit();
}
}
}
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.google.com")
driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")
# Get attribute of current active element
attr = driver.switch_to.active_element.get_attribute("title")
print(attr)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace ActiveElement {
class ActiveElement {
public static void Main(string[] args) {
IWebDriver driver = new ChromeDriver();
try {
// Navigate to Url
driver.Navigate().GoToUrl("https://www.google.com");
driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");
// Get attribute of current active element
string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
System.Console.WriteLine(attr);
} finally {
driver.Quit();
}
}
}
}
driver.find_element(css: '[name="q"]').send_keys('webElement')
attr = driver.switch_to.active_element.attribute('title')
const {Builder, By} = require('selenium-webdriver');
(async function example() {
let driver = await new Builder().forBrowser('chrome').build();
await driver.get('https://www.google.com');
await driver.findElement(By.css('[name="q"]')).sendKeys("webElement");
// Get attribute of current active element
let attr = await driver.switchTo().activeElement().getAttribute("title");
console.log(`${attr}`)
})();
import org.openqa.selenium.By
import org.openqa.selenium.chrome.ChromeDriver
fun main() {
val driver = ChromeDriver()
try {
driver.get("https://www.google.com")
driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")
// Get attribute of current active element
val attr = driver.switchTo().activeElement().getAttribute("title")
print(attr)
} finally {
driver.quit()
}
}