456 Stimmen

Gibt es eine Möglichkeit, Element durch XPath mit JavaScript in Selenium WebDriver zu erhalten?

Ich bin auf der Suche nach etwas wie:

getElementByXpath(//html[1]/body[1]/div[1]).innerHTML

Ich brauche, um die innerHTML von Elementen mit JS zu erhalten (zu verwenden, dass in Selenium WebDriver/Java, da WebDriver es selbst nicht finden kann), aber wie?

Ich könnte das ID-Attribut verwenden, aber nicht alle Elemente haben ein ID-Attribut.

[FIXED]

Ich verwende jsoup, um dies in Java zu erreichen. Das funktioniert für meine Bedürfnisse.

737voto

yckart Punkte 29968

Sie können verwenden document.evaluate :

Wertet eine XPath-Ausdruckskette aus und re angegebenen Typs zurück, falls möglich.

Sie ist w3-standardisiert und vollständig dokumentiert: https://developer.mozilla.org/en-US/docs/Web/API/Document.evaluate

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

console.log( getElementByXpath("//html[1]/body[1]/div[1]") );

<div>foo</div>

https://gist.github.com/yckart/6351935

Es gibt auch eine großartige Einführung im Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Alternative Version, mit XPathEvaluator :

function getElementByXPath(xpath) {
  return new XPathEvaluator()
    .createExpression(xpath)
    .evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE)
    .singleNodeValue
}

console.log( getElementByXPath("//html[1]/body[1]/div[1]") );

<div>foo/bar</div>

317voto

Dmitry Semenyuk Punkte 3039

In Chrome Dev Tools können Sie folgendes ausführen:

$x("some xpath")

37voto

undetected Selenium Punkte 147423

Zur Identifizierung eines WebElement mit xpath y javascript müssen Sie die evaluate() Methode, die eine xpath Ausdruck und gibt ein Ergebnis zurück.


document.evaluate()

document.evaluate() gibt eine XPathResult basierend auf einem XPath Ausdruck und andere gegebene Parameter.

Die Syntax lautet:

var xpathResult = document.evaluate(
  xpathExpression,
  contextNode,
  namespaceResolver,
  resultType,
  result
);

Wo:

  • xpathExpression : Die Zeichenkette, die den auszuwertenden XPath darstellt.
  • contextNode : Gibt den Kontextknoten für die Abfrage an. Übliche Praxis ist die Übergabe von document als Kontextknoten.
  • namespaceResolver : Die Funktion, der alle Namespace-Präfixe übergeben werden und die eine Zeichenkette zurückgeben sollte, die den mit diesem Präfix verbundenen Namespace-URI darstellt. Sie wird verwendet, um Präfixe im XPath selbst aufzulösen, so dass sie mit dem Dokument abgeglichen werden können. null ist üblich für HTML-Dokumente oder wenn keine Namensraum-Präfixe verwendet werden.
  • resultType : Eine ganze Zahl, die dem Typ des XPathResult-Ergebnisses entspricht, das mit benannte konstante Eigenschaften , wie zum Beispiel XPathResult.ANY_TYPE des XPathResult-Konstruktors, die den ganzen Zahlen von 0 bis 9 entsprechen.
  • result : Ein bestehendes XPathResult, das für die Ergebnisse verwendet werden soll. null ist die gebräuchlichste und erzeugt ein neues XPathResult

Demonstration

Ein Beispiel dafür ist die Suchfeld innerhalb der Google-Startseite die eindeutig mit Hilfe des xpath como //*[@name='q'] kann auch mit Hilfe der google-chrome-devtools Konsole durch den folgenden Befehl:

$x("//*[@name='q']")

Schnappschuss:

googlesearchbox_xpath

Das gleiche Element kann auch mit document.evaluate() und die xpath Ausdruck wie folgt:

document.evaluate("//*[@name='q']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

Schnappschuss:

document_evalute_xpath

31voto

Jay Punkte 3649

Für etwas wie $x aus der Chrome-Befehlszeilen-Api (um mehrere Elemente auszuwählen) versuchen:

var xpath = function(xpathToExecute){
  var result = [];
  var nodesSnapshot = document.evaluate(xpathToExecute, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
  for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ ){
    result.push( nodesSnapshot.snapshotItem(i) );
  }
  return result;
}

Diese MDN-Übersicht war hilfreich: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

16voto

ggorlen Punkte 32765

Obwohl viele Browser über $x(xPath) in die Konsole integriert ist, finden Sie hier eine Zusammenstellung der nützlichen, aber hart kodierten Schnipsel aus Einführung in die Verwendung von XPath in JavaScript bereit zur Verwendung in Skripten:

Schnappschuss

Dies ergibt einen einmaligen Schnappschuss der xpath-Ergebnismenge. Die Daten können nach DOM-Mutationen veraltet sein.

const $x = xp => {
  const snapshot = document.evaluate(
    xp, document, null, 
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null
  );
  return [...Array(snapshot.snapshotLength)]
    .map((_, i) => snapshot.snapshotItem(i))
  ;
};

console.log($x('//h2[contains(., "foo")]'));

<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>

Erster bestellter Knoten

const $xOne = xp => 
  document.evaluate(
    xp, document, null,
    XPathResult.FIRST_ORDERED_NODE_TYPE, null
  ).singleNodeValue
;

console.log($xOne('//h2[contains(., "foo")]'));

<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>

Iterator

Beachten Sie jedoch, dass die Iteration ungültig wird, wenn das Dokument zwischen den Iterationen verändert wird (der Dokumentenbaum wird geändert) und die invalidIteratorState Eigenschaft von XPathResult wird eingestellt auf true und eine NS_ERROR_DOM_INVALID_STATE_ERR wird eine Ausnahme ausgelöst.

function *$xIter(xp) {
  const iter = document.evaluate(
    xp, document, null, 
    XPathResult.ORDERED_NODE_ITERATOR_TYPE, null
  );

  for (;;) {
    const node = iter.iterateNext();

    if (!node) {
      break;
    }

    yield node;
  }
}

// dump to array
console.log([...$xIter('//h2[contains(., "foo")]')]);

// return next item from generator
const xpGen = $xIter('//h2[text()="foo"]');
console.log(xpGen.next().value);

<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X