簡體   English   中英

檢查元素是否存在 Python Selenium

[英]Checking if an element exists with Python Selenium

我有個問題; 我是用Selenium(Firefox)web驅動打開一個網頁,點擊幾個鏈接等,然后截圖。

我的腳本在 CLI 中運行良好,但是當通過cron 作業運行時,它沒有通過第一個 find_element() 測試。 我需要添加一些調試,或幫助我找出失敗原因的東西。

基本上,在進入登錄頁面之前,我必須單擊“登錄”錨點。 元素的構造是:

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

我正在使用find_element By LINK_TEXT 方法:

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

A) 我如何檢查鏈接是否真的被 Python 拾取了? 我應該使用 try/catch 塊嗎?

B) 是否有比 LINK_TEXT 更好/更可靠的定位DOM元素的方法? 例如,在jQuery中,您可以使用更具體的選擇器 $('a.lnk:contains(log in)').do_something();


我已經解決了主要問題,這只是手指的麻煩。 我用不正確的參數調用腳本 - 一個簡單的錯誤。

我仍然想要一些關於如何檢查元素是否存在的指示。 此外,還有一個隱式/顯式等待的示例/解釋,而不是使用糟糕的 time.sleep() 調用。

一種)

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 作為所有腳本的標准,並創建如上所述的通用函數。

更新:我在 4 年前寫了最初的答案,當時我認為 xpath 是最好的選擇。 現在我建議使用css selectors 我仍然建議不要混合/使用“按 id”、“按名稱”等,而是使用一種方法。

提供的解決方案對我來說似乎都不是最簡單的,所以我想添加我自己的方式。

基本上,您獲得元素列表,而不僅僅是元素,然后計算結果; 如果它為零,則它不存在。 例子:

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

注意find_elements_by_css_selector的“s”以確保它是可數的。

編輯:我正在檢查列表的len( ,但我最近了解到空列表是錯誤的,因此您根本不需要獲取列表的長度,而是使用更簡單的代碼。

另外,另一個答案說使用 xpath 更可靠,但事實並非如此。 請參閱css-selector 和 Xpath 有什么區別? 哪個更好(根據性能和跨瀏覽器測試)?

A) 是的。 檢查元素是否存在的最簡單方法是在try/catch簡單地調用find_element

B) 是的,我總是嘗試在不使用文本的情況下識別元素,原因有兩個:

  1. 文本更有可能改變;
  2. 如果這對您很重要,您將無法針對本地化構建運行測試。

解決方案:

  1. 您可以使用 xpath 查找具有 ID 或其他唯一標識符的父元素或祖先元素,然后找到匹配的子元素/后代元素或;
  2. 您可以為鏈接本身請求 ID 或名稱或其他一些唯一標識符。

對於后續問題,使用try/catch可以判斷元素是否存在,並且可以在此處找到等待的好示例: http : //seleniumhq.org/docs/04_webdriver_advanced.html

沒有 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

與布賴恩相同,但從 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)

你也可以更簡潔地使用

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

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'

使用最新的 Selenium,您現在可以使用您現在可以使用.is_displayed()

https://www.selenium.dev/documentation/webdriver/elements/information/

你可以像下面這樣使用 is_displayed()

res = driver.find_element_by_id("some_id").is_displayed()
assert res, 'element not displayed!'

如果數組的長度等於 0 元素不存在,您可以通過可用的方法查找元素並檢查響應數組長度。

element_exist = False if len(driver.find_elements_by_css_selector('div.eiCW-')) > 0 else True

當您知道元素不存在時,隱式等待可能是一個問題。 我創建了一個簡單的上下文管理器來避免那些等待時間

class PauseExplicitWait(object):
    """
    Example usage:

    with PauseExplicitWait(driver, 0):
        driver.find_element(By.ID, 'element-that-might-not-be-there')
    """
    def __init__(self, driver, new_wait=0):
        self.driver = driver
        self.original_wait = driver.timeouts.implicit_wait
        self.new_wait = new_wait
      
    def __enter__(self):
        self.driver.implicitly_wait(self.new_wait)
  
    def __exit__(self, exc_type, exc_value, exc_tb):
        self.driver.implicitly_wait(self.original_wait)
  

您可以通過 find_elements 檢查,如果結果為空,則該元素不存在

if driver.find_elements(By.SOMETHING, "#someselector") == []:
    continue   # that element is not exist

A)使用.is_displayed()如解釋

https://www.selenium.dev/documentation/webdriver/elements/information/

# After navigating to the url
# Get boolean value for is element display
is_button_visible = driver.find_element(By.CSS_SELECTOR, "[name='login']").is_displayed()

使用“is_button_visible”繼續您的代碼邏輯進行分支。

B)參考@Sam Woods 接受的答案

el = WebDriverWait(driver, timeout=3).until(lambda d: d.find_element(By.TAG_NAME,"p"))

文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM