查询网络元素
使用 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>
第一个匹配的元素
许多定位器会匹配页面上的多个元素。 单个的 find element 方法会返回在给定上下文中找到的第一个元素的引用。
在整个 DOM 中查找
当在 driver 实例上调用 find element 方法时, 它会返回 DOM 中与所提供定位器匹配的第一个元素的引用。 该引用可以被保存并用于后续的元素操作。 在上面的示例 HTML 中,有两个 class 名称为 “tomatoes” 的元素, 因此此方法会返回位于 “vegetables” 列表中的那个元素。
WebElement vegetable = driver.findElement(By.className("tomatoes"));
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
driver.find_element(class: 'tomatoes')const vegetable = await driver.findElement(By.className('tomatoes'));
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
在 DOM 的子集内评估
与其在整个 DOM 中寻找唯一的定位器, 通常更有用的是将搜索范围缩小到另一个已定位元素的作用域内。 在上面的示例中,有两个 class 名为 “tomatoes” 的元素, 因此要获取第二个元素的引用会更具挑战性。
一种解决办法是先定位一个具有唯一属性的元素,
该元素是目标元素的祖先但不是非目标元素的祖先,
然后在该对象上调用 find element:
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')
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 已支持通过易用的 shadow root 方法访问该树。注意:这些方法需要 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')优化后的定位器
嵌套查找可能不是最有效的定位策略, 因为它需要向浏览器发送两次独立的命令。
为略微提升性能,我们可以使用 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"));
driver.find_element(css: '#fruits .tomatoes')const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
所有匹配的元素
在某些情况下,需要获取与定位器匹配的所有元素的引用,而不是仅获取第一个。
复数形式的 find elements 方法会返回一组元素引用。如果没有匹配项,则返回空列表。
在本例中,将返回所有水果和蔬菜列表项的引用集合。
List<WebElement> plants = driver.findElements(By.tagName("li"));
plants = driver.find_elements(By.TAG_NAME, "li")
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
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 = element.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')
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()
}
}




