2016-09-28 102 views

回答

4

我已經看到這個問題在過去的一年左右會彈出幾次,我想試着寫這個功能...所以在這裏你去。它接受父元素並刪除每個孩子的textContent,直到剩下的是textNode。我已經在你的HTML上測試過了,它可以工作。

/** 
* Takes a parent element and strips out the textContent of all child elements and returns textNode content only 
* 
* @param e 
*   the parent element 
* @return the text from the child textNodes 
*/ 
public static String getTextNode(WebElement e) 
{ 
    String text = e.getText().trim(); 
    List<WebElement> children = e.findElements(By.xpath("./*")); 
    for (WebElement child : children) 
    { 
     text = text.replaceFirst(child.getText(), "").trim(); 
    } 
    return text; 
} 

,你叫它

System.out.println(getTextNode(driver.findElement(By.id("one")))); 
+0

這是一個很好的解決方案 – Dale

+0

@Dale有風險。考慮'

A button follows:
' - 通過這種方法你將得到的是:'A follow:button'。不完全是預期的 –

+0

@AdrianColomitchi是的..這不是完美的,但這是一個非常人爲的例子。幾乎不值得讚揚。 – JeffC

-1

你可以使用JavaScript來查找的文本。下面是一個C#示例

var script = @"var lastTextNode = document.createTreeWalker(arguments[0], NodeFilter.SHOW_TEXT, null, false).lastChild(); 
         if(lastTextNode == null) 
          return null; 
         return lastTextNode.textContent;"; 

var element = driver.FindElement(By.id('one')); 

IJavaScriptExecutor js = (IJavaScriptExecutor)driver; 
elementText = js.ExecuteScript(script, element).ToString(); 
+0

OP要求的Java。 – JeffC

+0

@JeffC,也許你應該再次閱讀這個問題。 OP問及如何在硒中進行。它只是用java標記的。 – shivansh

+0

是的..這就是你如何表明你想要什麼編程語言。你的答案不是用Selenium寫的......它是用Selenium的C#綁定書寫的......這不是OP要求的。如果你仔細閱讀過這個問題,你也會看到他的代碼不是用C#編寫的,而是用Java編寫的。在你採取態度之前,你應該檢查一下你的事實。 – JeffC

0

警告:初步解決方案(深下)將無法正常工作
我開了一個enhancement request: 2840對硒WebDrive和another one對W3C WebDrive規範 - 在更多的選票,越早他們會得到足夠的關注(人們可以希望)。在那之前,@shivansh在其他答案中提出的解決方案(通過Selenium執行JavaScript)仍然是唯一的選擇。下面是該解決方案的Java的適應(收集所有文本節點,丟棄所有那些只有空白,分離由\ t時的剩餘):

WebElement e=driver.findElement(By.xpath("//*[@id='one']")); 
if(driver instanceof JavascriptExecutor) { 
    String jswalker= 
     "var tw = document.createTreeWalker(" 
    + "arguments[0]," 
    + "NodeFilter.SHOW_TEXT," 
    + "{ acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT;} }," 
    + "false" 
    + ");" 
    + "var ret=null;" 
    + "while(tw.nextNode()){" 
    + "var t=tw.currentNode.wholeText.trim();" 
    + "if(t.length>0){" // skip over all-white text values 
    +  "ret=(ret ? ret+'\t'+t : t);" // if many, tab-separate them 
    + "}" 
    + "}" 
    + "return ret;" // will return null if no non-empty text nodes are found 
    ; 
    Object val=((JavascriptExecutor) driver).executeScript(jswalker, e); 
    // ---- Pass the context node here ------------------------------^ 
    String textNodesTabSeparated=(null!=val ? val.toString() : null); 
    // ----^ --- this is the result you want 
} 

參考文獻:

TreeWalker - 瀏覽器支持

Selenium Javascript Executor


初步建議的解決方案 - 不工作 - 看enhancement request: 2840

driver.findElement(By.id('one')).find(By.XPath("./text()").getText(); 

在單個搜索

driver.findElement(By.XPath("//[@id=one]/text()")).getText(); 

參見XPath spec/Location Pathschild::text()選擇器。

+2

org.openqa.selenium.InvalidSelectorException:無效的選擇器:xpath表達式的結果「.//* [@class ='global-alerts']/text()」是:[object Text]。它應該是一個元素。 – Dale

+0

Selenium不支持xpath的'text()'節點來定位.. –

+0

當我嘗試這個javascript時,我得到了所有文本元素在e下面(所以也來自子元素),並且只是直接的文本子元素問題是關於)... –

0

如果你使用:

String rawContent = driver.findElement(By.cssSelector("#one")).getText(); 

結果:

i am a button\n 
i am a button\n 
i am div 

如果你使用:

String info = driver.findElement(By.cssSelector("#one")).getText().split("\n")[2]; 

結果:

i am a div 
+1

你給的方式可能不是一個好的解決方案,子元素號是變量 – Dale

0

我用一個函數象下面這樣:

private static final String ALL_DIRECT_TEXT_CONTENT = 
     "var element = arguments[0], text = '';\n" + 
       "for (var i = 0; i < element.childNodes.length; ++i) {\n" + 
       " var node = element.childNodes[i];\n" + 
       " if (node.nodeType == Node.TEXT_NODE" + 
       " && node.textContent.trim() != '')\n" + 
       " text += node.textContent.trim();\n" + 
       "}\n" + 
       "return text;"; 

public String getText(WebDriver driver, WebElement element) { 
    return (String) ((JavascriptExecutor) driver).executeScript(ALL_DIRECT_TEXT_CONTENT, element); 
} 
相關問題