按文本查找元素并获取xpath - selenium webdriver junit
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按文本查找元素并获取xpath - selenium webdriver junit相关的知识,希望对你有一定的参考价值。
我的网页上有一个包含9行和6列的表格。我想搜索文本“MakeGoodDisabled-Programwise_09_44_38_461(n)”并获取单元格的xpath。我使用了以下但它失败了,因为它无法在页面上找到文本。你能帮忙吗?我正在使用Selenium Webdriver Junit对此进行编码。
List < WebElement > links = driver.findElements(By.tagName("td"));
Iterator < WebElement > itr = links.iterator();
while (itr.hasNext()) {
String test = itr.next().getText();
if (test.equals("MakeGoodDisabled-Programwise_09_44_38_461(n)")) {
String xpath = driver.findElement(By.name(test)).getAttribute("xpath");
System.out.println(xpath);
}
}
我的目的是在表中查找文本并在同一行中获取相应的下一列值。我以为我会用我想要的列号取代xpath找到的列号。有没有更好的方法来做到这一点
当然有办法。这是一种可能的解决方案。
获取所有行:
While (iterate over row)
While(Iterate over column)
if(column.Text=='YOUR_MATCH'){
int voila=column.Index
}
}
}
现在您只需移动到其他行的特定索引;或者您可以使用像.../tr/td[voila]
这样的xpath来检索该特定列的所有单元格。
我写了一个方法,请不要把它当作实际工作代码!
我认为它们不是用于获取搜索元素的xpath的任何特殊函数。为此,首先需要手动查找元素,然后通过getXpath函数获取xpath。
我的java方法获取绝对xpath:
public static String getXpath(WebElement element){
int n = element.findElements(By.xpath("./ancestor::*")).size();
String path = "";
WebElement current = element;
for(int i = n; i > 0; i--){
String tag = current.getTagName();
int lvl = current.findElements(By.xpath("./preceding-sibling::" + tag)).size() + 1;
path = String.format("/%s[%d]%s", tag, lvl, path);
current = current.findElement(By.xpath("./parent::*"));
}
return "/" + current.getTagName() + path;
}
并为相对xpath(这是第一个:)):
public static String getXpath(WebElement self, WebElement ancestor){
int a = ancestor.findElements(By.xpath("./ancestor::*")).size();
int s = self.findElements(By.xpath("./ancestor::*")).size();
String path = "";
WebElement current = self;
for(int i = s - a; i > 0; i--){
String tag = current.getTagName();
int lvl = current.findElements(By.xpath("./preceding-sibling::" + tag)).size() + 1;
path = String.format("/%s[%d]%s", tag, lvl, path);
current = current.findElement(By.xpath("./parent::*"));
}
return path;
}
您还可以使用它来爬网并生成xpath:
用下面的方法调用
generateXPATH(element, "");
输出将是这样的:
/html[1]/body[1]/div[5]/div[1]/div[2]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/form[1]/div[2]/div[1]/input[2]
方法
private String generateXPATH(WebElement childElement, String current) {
String childTag = childElement.getTagName();
if(childTag.equals("html")) {
return "/html[1]"+current;
}
WebElement parentElement = childElement.findElement(By.xpath(".."));
List<WebElement> childrenElements = parentElement.findElements(By.xpath("*"));
int count = 0;
for(int i=0;i<childrenElements.size(); i++) {
WebElement childrenElement = childrenElements.get(i);
String childrenElementTag = childrenElement.getTagName();
if(childTag.equals(childrenElementTag)) {
count++;
}
if(childElement.equals(childrenElement)) {
return generateXPATH(parentElement, "/" + childTag + "[" + count + "]"+current);
}
}
return null;
}
你问的问题对我没有任何意义。我想你可能有充分理由“想要去做”!
你的代码行
String xpath = driver.findElement(By.name(test)).getAttribute("xpath");
因为html元素中没有属性'xpath',所以不会返回任何内容。请清楚了解xpath的含义?
如果我有一个html元素,如下所示
<input name = "username" value = "Name" readonly ="readonly">
我可以通过使用获取属性的值
driver.findElement(By.name("username").getAttribute("value"); // returns 'Name'
这将给出“价值”属性的价值
要么
driver.findElement(By.name("username").getAttribute("readonly"); // returns 'readonly'
和上面一样!
元素的XPath不是确定值。许多XPath都可以找到一个元素。
您无法使用Webdriver提取XPath,即使可以,也不可能是最有效或最明智的,只能由自动机定义。
您可以使用javascript生成xpath:
function getPathTo(element) {
// only generate xpaths for elements which contain a particular text:
if (element.innerText == "MakeGoodDisabled-Programwise_09_44_38_461(n)") {
// use id to produce relative paths rather than absolute, whenever possible
if ((element.id !== '') && (element.id != 'undefined')) {
return 'id("' + element.id + '")';
}
// stop looping when you get to the body tag
if (element === document.body) {
return element.tagName;
}
// calculate position among siblings
var ix = 0;
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
if (sibling === element) {
return getPathTo(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
}
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
ix++;
}
}
}
}
// put all matching xpaths in an array
var allXPaths = [];
// if you know the particular tag you are looking for, replace * below to optimize
var allTags = document.getElementsByTagName('*');
for (i = 0; i < allTags.length; i++) {
if ((getPathTo(allTags[i]).indexOf('/HEAD') == -1) && (getPathTo(allTags[i]).indexOf('undefined') == -1)) {
allXPaths.push(getPathTo(allTags[i]));
console.log(getPathTo(allTags[i]));
}
}
return allXPaths;
如果你把这个JavaScript放在一个名为getXPaths
的字符串中然后在Java中,你可以像这样执行它:
ArrayList<String> xpaths = (ArrayList<String>) js.executeScript(getXPaths);
它返回一个数组而不是一个String,因为如果你的页面恰好有更少或更多匹配了tagname / innerText的元素,你就会想知道。你可以通过数组的大小来判断。
JavaScript函数生成XPath
XPath / locator是一种通过浏览Tree结构来寻址元素的方法。
绝对XPath(/):/ html / body / div [5] / div [4]
WebElement XPath:
function WebElement_XPath(element) {
if (element.tagName == 'HTML') return '/html';
if (element===document.body) return '/html/body';
// calculate position among siblings
var position = 0;
// Gets all siblings of that element.
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
// Check Siblink with our element if match then recursively call for its parent element.
if (sibling === element) return WebElement_XPath(element.parentNode)+'/'+element.tagName+'['+(position+1)+']';
// if it is a siblink & element-node then only increments position.
var type = sibling.nodeType;
if (type === 1 && sibling.tagName === element.tagName) position++;
}
}
MouseEvent XPath:
var eventXPath = '';
function MouseEvent_XPath(e) {
event = e.target || e.srcElement ||e.originalTarget;
for ( var xpathEle = ''; event && event.nodeType == 1; event = event.parentNode ) {
if ( event.tagName == 'HTML' || event.tagName == 'html' ) {
eventXPath = '//html'+xpathEle; break;
}
if ( event.tagName == 'BODY' || event.tagName == 'body' ) {
eventXPath = '//html/body'+xpathEle; break;
}
// calculate position among siblings
var position = 0;
// Gets all siblings of that event.
var siblings = event.parentNode.children;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
// Check Sibling with our event if match then recursively call for its parent event.
if (sibling === event) xpathEle = "/"+event.tagName+'['+(position+1)+']'+xpathEle;
// if it is a sibling with same tagName then only increments position.
if (sibling.tagName ==以上是关于按文本查找元素并获取xpath - selenium webdriver junit的主要内容,如果未能解决你的问题,请参考以下文章
Selenium XPath 合并跨越文本并查找包含子字符串的元素
使用 selenium 函数按名称查找元素时元素不可交互,但在通过 xpath 方法使用查找元素时有效