web-dev-qa-db-ja.com

Python Seleniumで要素が存在するかどうかを確認する

問題があります-Selenium(firefox)Webドライバーを使用してWebページを開き、いくつかのリンクをクリックするなどして、スクリーンショットをキャプチャしています。

私のスクリプトはCLIから正常に実行されますが、cronjobを介して実行された場合、最初のfind_element()テストを通過していません。デバッグを追加するか、失敗した理由を理解するために何かを追加する必要があります。

基本的に、ログインページに移動する前に「ログイン」アンカーをクリックする必要があります。要素の構造は次のとおりです。

<a class="lnk" rel="nofollow" href="/login.jsp?destination=/secure/Dash.jspa">log in</a>

私はLINK_TEXTによるfind_elementメソッドを使用しています:

login = driver.find_element(By.LINK_TEXT, "log in").click()

私はPython Noobなので、言語と少し戦っています...

A)リンクが実際にPythonによってピックアップされていることを確認するにはどうすればよいですか? try/catchブロックを使用する必要がありますか?

B)LINK_TEXTよりもDOM要素を見つけるためのより良い/より信頼できる方法はありますか?例えば。 JQueryでは、より具体的なセレクター$( 'a.lnk:contains(log in)')。do_something();を使用できます。


私は主な問題を解決しましたが、それはちょうど指のトラブルでした-私は間違ったパラメータでスクリプトを呼び出していました-単純な間違い。

要素が存在するかどうかを確認する方法についてのポインタが必要です。また、くだらないtime.sleep()呼び出しを使用する代わりに、暗黙的/明示的な待機の例/説明。

乾杯、NS

51
nonshatter

A)はい。要素が存在するかどうかを確認する最も簡単な方法は、find_element内でtry/catchを呼び出すだけです。

B)はい、私は常に2つの理由でテキストを使用せずに要素を識別しようとします:

  1. テキストが変更される可能性が高くなります。
  2. あなたにとって重要な場合、ローカライズされたビルドに対してテストを実行することはできません。

解決策:

  1. Xpathを使用して、IDまたは他の一意の識別子を持つ親または先祖要素を検索し、次に一致する子または子孫を見つけることができます;
  2. リンク自体のIDまたは名前、または他の一意の識別子を要求できます。

フォローアップの質問については、try/catchを使用すると、要素が存在するかどうかを確認でき、待機の良い例がここにあります: http://seleniumhq.org/docs/04_webdriver_advanced.html

46
Sam Woods

a)

from Selenium.common.exceptions import NoSuchElementException        
def check_exists_by_xpath(xpath):
    try:
        webdriver.find_element_by_xpath(xpath)
    except NoSuchElementException:
        return False
    return True

b) xpathを使用します-最も信頼性の高いものです。 さらに、すべてのスクリプトでxpathを標準として使用し、上記の汎用機能用の関数を作成できます。

[〜#〜] update [〜#〜]:4年以上前に最初の答えを書きましたが、当時はxpathが最良の選択肢だと思っていました。 css selectorsを使用することをお勧めします。 「by id」や「by name」などを混ぜて使用しないことをお勧めします。代わりに1つのアプローチを使用します。

78
Alex Okrushko

提供されているソリューションはどれも私にとって最も簡単なものではなかったので、独自の方法を追加したいと思います。

基本的に、要素だけではなく要素のリストを取得して、結果をカウントします。ゼロの場合、存在しません。例:

if driver.find_elements_by_css_selector('#element'):
    print "Element exists"

find_elements_by_css_selectorの「s」に注意して、カウント可能であることを確認してください。

[〜#〜] edit [〜#〜]:リストのlen(をチェックしていましたが、最近、空のリストは偽であるため、リストの長さを取得する必要はまったくなく、より単純なコードのままです。

また、別の回答では、xpathを使用する方が信頼性が高いと言われていますが、これは事実ではありません。 css-selectorとXpathの違いは何ですか?どちらが優れていますか(パフォーマンスによると、クロスブラウザーテストについて)?

44
Brian Leishman

Try&catchおよび新規インポートなしのソリューション:

if len(driver.find_elements_by_id('blah')) > 0: #pay attention: find_element*s*
    driver.find_element_by_id('blah').click #pay attention: find_element
3
Super Mario

ブライアンと同じですが、tstempkoからのこの回答に追加します。

https://sqa.stackexchange.com/questions/3481/quicker-way-to-assert-that-an-element-does-not-exist

だから私は試しましたが、すぐに動作します:

driver.implicitly_wait(0)

if driver.find_element_by_id("show_reflist"):        
 driver.find_element_by_id("show_reflist").find_element_by_tag_name("img").click()

この後、デフォルト値を復元します

driver.implicitly_wait(30)
2
vmk

driver.find_element_by_id("some_id").size()はクラスメソッドです。

必要なのは:

driver.find_element_by_id("some_id").sizeこれは辞書なので:

if driver.find_element_by_id("some_id").size['width'] != 0 : print 'button exist'

0
Lopi Dani

また、より簡潔に使用することもできます

driver.find_element_by_id("some_id").size() != 0
0
codeslord