wake-up-neo.com

Wie finde ich in Selenium Webdriver (Python) ein Element, das bestimmten Text enthält

Ich versuche, eine komplizierte Javascript-Schnittstelle mit Selenium zu testen (unter Verwendung der Python-Schnittstelle und über mehrere Browser hinweg). Ich habe eine Reihe von Schaltflächen des Formulars:

<div>My Button</div>

Ich möchte in der Lage sein, nach Schaltflächen zu suchen, die auf "Meine Schaltfläche" (oder auf Groß- und Kleinschreibung, teilweise Übereinstimmungen wie "Meine Schaltfläche" oder "Schaltfläche") basieren.

Ich finde das erstaunlich schwierig, soweit ich das Gefühl habe, dass mir etwas fehlt, was offensichtlich ist. Das Beste, was ich bisher habe, ist:

driver.find_elements_by_xpath('//div[contains(text(), "' + text + '")]')

Dies ist jedoch die Groß- und Kleinschreibung. Die andere Sache, die ich versucht habe, ist das Durchlaufen aller divs auf der Seite und das Überprüfen der Eigenschaft element.text. Sie erhalten jedoch jedes Mal eine Situation der Form:

<div class="outer"><div class="inner">My Button</div></div>

div.outer hat auch "My Button" als Text. Um das zu beheben, habe ich versucht herauszufinden, ob div.outer das übergeordnete Element von div.inner ist, aber ich konnte nicht herausfinden, wie das geht (element.get_element_by_xpath ('..') gibt das übergeordnete Element eines Elements zurück, aber es Tests nicht gleich div.outer). Auch das Durchlaufen aller Elemente auf der Seite scheint sehr langsam zu sein, zumindest mit dem Chrome-Web-Treiber.

Ideen?

Edit: Diese Frage wurde etwas vage. Gefragt (und beantwortet) eine spezifischere Version hier: Wie erhalte ich einen Text eines Elements in Selenium WebDriver (über die Python-API), ohne Child-Element-Text einzuschließen?

182
josh

Versuche Folgendes:

driver.find_elements_by_xpath("//*[contains(text(), 'My Button')]")
232
Ricky

sie könnten einen XPath versuchen wie:

'//div[contains(text(), "{0}") and @class="inner"]'.format(text)
22
andrean

Sie können es auch mit Page Object Pattern verwenden, z.

Versuchen Sie diesen Code: 

@FindBy(xpath = "//*[contains(text(), 'Best Choice')]")
WebElement buttonBestChoice;
10

// * sucht nach einem beliebigen HTML-Tag. Wo, wenn Text für Button und Div-Tag üblich ist, und wenn // * Kategorien sind, funktioniert er nicht wie erwartet. Wenn Sie ein bestimmtes Element auswählen müssen, können Sie es erhalten, indem Sie das HTML-Element-Tag deklarieren. Mögen:

driver.find_element_by_xpath("//div[contains(text(),'Add User')]")
driver.find_element_by_xpath("//button[contains(text(),'Add User')]")
4
Ishita Shah
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), 'YourTextHere')]")));
    assertNotNull(driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")));
    String yourButtonName=driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")).getAttribute("innerText");
    assertTrue(yourButtonName.equalsIgnoreCase("YourTextHere"));
2
mike oganyan

Interessanterweise drehen sich praktisch alle Antworten um die Funktion contains() von xpath und vernachlässigen dabei die Tatsache, dass zwischen Groß- und Kleinschreibung unterschieden wird sensitive - im Gegensatz zu OPs ask.
Wenn Sie die Groß-/Kleinschreibung nicht berücksichtigen möchten, können Sie dies in xpath 1.0 (Unterstützung der aktuellen Browserversion) tun, obwohl dies mit der Funktion translate() nicht sehr schön ist. Durch die Verwendung einer Übersetzungstabelle wird ein Quellzeichen in die gewünschte Form gebracht.

Wenn Sie eine Tabelle mit allen Großbuchstaben erstellen, wird der Text des Knotens effektiv in die untere () -Form umgewandelt, sodass bei der Suche nach hier nur das Vorrecht zwischen Groß- und Kleinschreibung unterschieden werden kann.

[
  contains(
    translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'my button'
  )
]
# will match a source text like "mY bUTTon"

Der vollständige Python-Aufruf:

driver.find_elements_by_xpath("//*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZЙ', 'abcdefghijklmnopqrstuvwxyzй'), 'my button')]")

Natürlich hat dieser Ansatz seine Nachteile - wie angegeben, funktioniert er nur für lateinischen Text. Wenn Sie Unicode-Zeichen erfassen möchten, müssen Sie diese der Übersetzungstabelle hinzufügen. Ich habe das im obigen Beispiel getan - das letzte Zeichen ist das kyrillische Symbol "Й".


Und wenn wir in einer Welt gelebt hätten, in der Browser xpath 2.0 und höher unterstützen (????, aber nicht in Kürze soon), hätten wir die Funktionen lower-case() (noch) nicht vollständig für das Gebietsschema geeignet) und matches (für reguläre Suchanfragen mit Flag, bei dem die Groß-/Kleinschreibung nicht berücksichtigt wird ('i')).

1
Todor Minakov

Verwenden Sie die driver.find_elements_by_xpath und Matches regex-Übereinstimmungsfunktion für die case-abhängige Suche des Elements anhand seines Textes.

driver.find_elements_by_xpath("//*[matches(.,'My Button', 'i')]")
0
Andriy Ivaneyko

Ähnliches Problem: <button>Advanced...</button> suchen

Vielleicht gibt Ihnen das einige Anregungen (bitte übertragen Sie das Konzept von Java nach Python):

wait.until(ExpectedConditions.elementToBeClickable(//
    driver.findElements(By.tagName("button")).stream().filter(i -> i.getText().equals("Advanced...")).findFirst().get())).click();
0
Reto Höhener