xpath式を使用して、品目モデル番号からテキスト64076を削る方法

I'm attempting to scrape the text 64076 next to Item model number: on this page using the following XPath expression:

//*[contains (@id,'productDetails')]//tr[contains(.,'Item model number')]/td|//*[contains (@id,'detail')]//descendant::li[contains(.,'Item model number')]/text()//I'm focusing mainly on second half of expression..

ただし、これはFirebugで予想されるテキスト(64076)と一致しますが、Selenium WebDriver(Java)を使用している場合は見つかりません。

XPathを次のように変更すると、

//*[contains (@id,'productDetails')]//tr[contains(.,'Item model number')]/td|//*[contains (@id,'detail')]//descendant::li[contains(.,'Item model number')]

それは動作しますがそれはまた私がしたくないというテキストアイテムのモデル番号:を削り取る(私は正規表現を使用して結果を解析することができる知っているが、私はなぜ私のXPath太字ではなく text()で実際のテキスト/番号を明確に一致させる)

ありがとう

0

6 答え

このページをクリックするには、 WebDriverWait を使用して要素を設定します。目に見えるようにしてくださいそして、あなたは次の解決策を使うことができます:

  • Code Block:

    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class q52359631_textExtract {
    
        public static void main(String[] args) {
            System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
            WebDriver driver = new FirefoxDriver();
            driver.get("https://www.amazon.com/dp/B000TW3B9G/?tag=stackoverflow17-20");
            WebElement myElement = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//td[@class='bucket']//li/b[contains(.,'Item model number:')]/..")));
            String myText = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].lastChild.textContent;", myElement);
            System.out.println(myText);
        }
    }
    
  • Console Output:

     64076
    
0
追加された

これは、 text()を含まないXPath 1.0しかサポートしていないため、Seleniumでは一般的な問題です。通常の方法は、ノードを取得して getText()を呼び出すことです。

Here is a nicely wrapped function to get the text without any text from the children:

public static String geNodeText(WebElement element) {
  String text = element.getText();
  for (WebElement child : element.findElements(By.xpath("./*"))) {
    text = text.replaceFirst(child.getText(), "");
  }
  return text;
}

もちろん、文字列関数や正規表現を使って問題の文字列を抽出することもできます。しかしこれはおそらくあなたが各ケースのためのカスタム抽出ロジックを書くことを必要とします。

0
追加された

それはXPathの text()がTextNodeを見つけることを意味するためですが、SeleniumではElementNodeを見つけて返すことのみをサポートします。また、属性ノードはSeleniumではサポートされていませんが、XPathではサポートされています。

あなたはTextNodeの親(これはElementNodeです)を見つけなければなりませんそしてそれからあなたが欲しい文字列を抽出するために正規表現かsplitを使います

String xpath = "//ul/li[b[text()='Item model number:']][contains(. , '64076')]"
driver.findElement(By.xpath(xpath)).getText().split()[1]
0
追加された

More in @Bauban Answer. Selenium doesn't allow to locate an element using text node. You can try with evaluate() method of JavaScript and evaluate your xpath using JavascriptExecutor

これはあなたのxpathです。

//div[@class='content']//li[contains(.,'Item model number:')]/text()

そして、これはあなたが評価することができる方法です:

JavascriptExecutor JS = (JavascriptExecutor)driver;
Object message = js.executeScript("var value = document.evaluate(\"//div[@class='content']//li[contains(.,'Item model number:')]/text()\",document, null, XPathResult.STRING_TYPE, null ); return value.stringValue;");
System.out.println(message.toString().trim());

詳細についてはこちらを参照してください関数を評価します。

0
追加された

Try for Item model number: 64076 for the test URL

var xpathExp = 
    "//h2[.='Product details']//parent::td//div[@class='content']/ul/li/b[contains(text(),'Item')]/parent::li/text()";
var ele = $x(xpathExp);
console.dir( ele );//Array(1)
console.log( ele[0] ); //" 64076"

XMLをテストする XPathオンライン

  • Item model number: 64076

XML Tree View codebeautify //ul/li/b[contains(text(),'Item')]/parent::li/text()

ul ..
li 64076 ..
b  Item model number: 

JavaScriptオブジェクトとしてのHTML

outerHTML:"
  • Item model number: 64076
  • " outerText:"Item model number: 64076" tagName:"LI" textContent:"Item model number: 64076" lastChild:text data: 64076" nodeValue: 64076" textContent: 64076" wholeText: 64076" lastElementChild:b
    0
    追加された

    TextNodeなので、Seleniumを使って直接取得することはできません。 JavaScriptを使用してテキストノードを確認して取得することができます。

    WebElement itemModelRootNode = driver.findElement(by.xpath("//*[contains (@id,'productDetails')]//tr[contains(.,'Item model number')]/td|//*[contains (@id,'detail')]//descendant::li[contains(.,'Item model number')]");
    
    String script = "var t = ''; arguments[0].childNodes.forEach((node)=>{ if(node.nodeType==Node.TEXT_NODE && node.textContent.trim().length > 0) { t = node.textContent.trim(); } }); return t;"
    
    String text = ((JavascriptExecutor)driver).executeScript(script, itemModelRootNode);
    
    0
    追加された