【问题标题】:Selenium Python Searching Element By 2 possible IDSelenium Python 通过 2 个可能的 ID 搜索元素
【发布时间】:2022-01-10 08:20:09
【问题描述】:

我想使用 ID 查找元素,但似乎网络有时会更改 ID。

有 2 个 ID,第一个 ID 可以让我直接输入电子邮件,但如果出现第二个 ID,我需要先单击一个按钮才能输入我的电子邮件。我试过使用ifelse 逻辑,但它显示了一些错误。 这是我的代码:

@pytest.mark.parametrize('a,b', key0)
def test_login_successful(self, a,b):
    time.sleep(5)
    if WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'login-find-account-form'))) == True:
        pass

    else:
    # WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'login-form')))
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
            (By.XPATH, '//*[@id="login-form"]/div[1]/div/div/div/a'))).click()

    email_box = '//*[@id="user_name"]'
    email_input = driver.find_element_by_xpath(email_box)
    email_input.send_keys(a)

    submit = driver.find_element_by_xpath('//*[@id="submit_button"]').click()
    

如果您有任何想法,我将不胜感激。

谢谢

【问题讨论】:

    标签: python selenium selenium-webdriver webdriver pytest


    【解决方案1】:

    您可以改用CSS 选择器,如下所示:

    ID_1 = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS, '#login-form,#login-find-account-form')))
    

    逗号用作 CSS 的 OR 运算符,如果它没有找到第一个,那么它将尝试找到第二个。请务必知道,此选择器不能用作 AND,这意味着它不会返回两个结果。

    编辑:

    有一种简单的方法可以实现这一点(不是正确的方法)。

    实现您需要的简单方法:

    @pytest.mark.parametrize('a,b', key0)
    def test_login_successful(self, a,b):
        time.sleep(5)
    
        # The element to be found on the second condition
        element_of_interest = driver.find_elements_by_xpath('//*[@id="login-form"]/div[1]/div/div/div/a')
    
        # element_of_interest is a list, if is empty this condition
        # is not valid and then it won't attempt to click on it
        if element_of_interest:
            element_of_interest[0].click()
    
        email_box = '//*[@id="user_name"]'
        email_input = driver.find_element_by_xpath(email_box)
        email_input.send_keys(a)
    
        submit = driver.find_element_by_xpath('//*[@id="submit_button"]').click()
    

    这里有几个cmets。看起来您实际上并不需要第一个条件,因为您在那里没有做任何事情。因此我只添加了第二个条件。

    如果您查看解决方案,您会发现使用find_elements_by_xpath(复数形式)而不是find_element_by_xpath,这是因为如果找不到该元素,那么find_elments_by_xpath 将返回一个空列表.

    如果您需要等待 10 秒直到其中一个元素出现,那么您可以执行以下操作:

    @pytest.mark.parametrize('a,b', key0)
    def test_login_successful(self, a,b):
        time.sleep(5)
    
        # The element to be found on the second condition
        element1 = driver.find_elements_by_id('login-find-account-form')
        element2 = driver.find_elements_by_xpath('//*[@id="login-form"]/div[1]/div/div/div/a')
    
        # Waits up to 10 seconds to find either element 1 or 2
        retries = 10
        while not element1 or not element2:
             time.sleep(1)
             retries -= 1
             if retries < 0:
                raise Exception("some exception in here")
             element1 = driver.find_elements_by_id('login-find-account-form')
             element2 = driver.find_elements_by_xpath('//*[@id="login-form"]/div[1]/div/div/div/a')
           
        # element2 is a list, if is empty this condition
        # is not valid and then it won't attempt to click on it
        if element2:
            element2[0].click()
    
        email_box = '//*[@id="user_name"]'
        email_input = driver.find_element_by_xpath(email_box)
        email_input.send_keys(a)
    
        submit = driver.find_element_by_xpath('//*[@id="submit_button"]').click()
    

    有一个更好的实现我建议看一下 Selenium 的页面对象模型文档,你可以从该设计模式中受益很多:https://www.selenium.dev/documentation/guidelines/page_object_models/

    【讨论】:

    • 感谢您的回答,但我没有完全解释我的情况。我已经编辑了我的问题。如果您能帮助我,我将不胜感激。
    猜你喜欢
    • 2021-05-18
    • 2021-10-18
    • 2021-06-22
    • 1970-01-01
    • 2015-06-05
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多