web-dev-qa-db-ja.com

Selenium Webdriver(Python)で特定のテキストを含む要素を見つけるにはどうすればよいですか?

私はSeleniumで(Pythonインターフェースを使用して、そして複数のブラウザーにわたって)複雑なJavaScriptインターフェースをテストしようとしています。私はフォームのボタンをいくつか持っています:

<div>My Button</div>

「マイボタン」(または「マイボタン」や「ボタン」などの大文字と小文字を区別しない、部分一致)に基づいてボタンを検索できるようにしたい

私はこれが驚くほど困難であると感じています。私がこれまでに持っている最高のことは:

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

ただし、これは大文字と小文字が区別されます。私が試したもう1つのことは、ページ上のすべてのdivを繰り返し処理し、element.textプロパティをチェックすることです。ただし、毎回次のような状況に陥ります。

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

div.outerにはテキストとして "My Button"もあります。これを解決するために、div.outerがdiv.innerの親であるかどうかを調べてみましたが、その方法がわかりませんでした(element.get_element_by_xpath( '..')が要素の親を返しますが、テストはdiv.outerと等しくありません)。また、少なくともChromeウェブドライバを使用した場合、ページ上のすべての要素を繰り返し処理するのは非常に遅いようです。

アイデア?

編集:この質問は少しあいまいになった。ここでより具体的なバージョンを尋ねた(そして答えました): 子要素のテキストを含めずに(Python APIを介して)Selenium WebDriverの要素のテキストを取得する方法?

199
josh

以下を試してください。

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

次のようにxpathを試すことができます。

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

Page Object Patternと一緒に使うこともできます。

このコードを試してください:

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

// * HTMLタグを探します。 Buttonとdivタグに共通のテキストがあり、// *がカテゴリの場合、期待通りに動作しません。特定のものを選択する必要がある場合は、HTML要素タグを宣言することによってそれを取得できます。好きです:

driver.find_element_by_xpath("//div[contains(text(),'Add User')]")
driver.find_element_by_xpath("//button[contains(text(),'Add User')]")
8
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

興味深いことに、事実上すべての答えはxpathの関数contains()を中心に展開し、大文字と小文字sensitiveであるという事実を無視します-OPの質問に反します。
大文字と小文字を区別する必要がない場合は、xpath 1.0(最新のブラウザーがサポートするバージョン)で実現できますが、きれいではありません- translate()を使用して 関数。変換テーブルを使用して、ソース文字を目的の形式に置き換えます。

すべて大文字のテーブルを作成すると、ノードのテキストがlower()形式に効果的に変換され、大文字と小文字を区別しないマッチング(ここでは特権のみ)が許可されます。

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

完全なpython呼び出し:

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

当然、このアプローチには欠点があります-与えられているように、ラテン語のテキストに対してのみ機能します。 Unicode文字をカバーする場合は、変換テーブルに追加する必要があります。上記のサンプルでこれを実行しました。最後の文字はキリル文字"Й"です。


そして、ブラウザがxpath 2.0以降をサポートする世界に住んでいた場合(????、しかしすぐには起こりません☹️)、関数 lower-case() (まだ、完全にロケールを認識しない)、および matches (正規表現検索の場合、大文字と小文字を区別しない('i')フラグ)。

1
Todor Minakov

テキストによる要素の大文字と小文字を区別しない検索には、 driver.find_elements_by_xpath および matches regexのマッチング関数を使用します。

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

同様の問題:<button>Advanced...</button>を探す

多分これはあなたにいくつかのアイデアを与えるでしょう(JavaからPythonへ概念を移してください):

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