如果无法找到元素,Selenium继续脚本

问题描述 投票:1回答:4

我有一个问题,当我访问一个网站,如果想检查元素是否显示和启用。如果是这种情况我想打印一些东西。如果元素未显示和启用,我想检查新元素,如果要打印某个元素,则显示该元素。我希望你明白这一点。

访问网站并且未检测到/显示第一个IF语句时,它会给出错误而不是转到下一个If语句。

错误:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //*[@id="errorLongContent"]

我已经尝试过使用try,expect并将if语句更改为elif。

我希望有一个人可以帮助我。

from selenium import webdriver
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options

# Setup browser for
options = Options()
profile = webdriver.FirefoxProfile()
driver = Firefox(executable_path='geckodriver', options=options, firefox_profile=profile)
driver.get("https://agar.io")

#Xpaths
PLAY_BUTTON_XPATH = '//*[@id="play"]'
PROXY_DENIES_CONNECTION = '//*[@id="errorLongContent"]'
TIMEOUT_XPATH1 = '//*[@id="errorTryAgain"]'


#checking for error
def mainfunction():
    while True:
        print("Starting")
        if driver.find_element_by_xpath(PROXY_DENIES_CONNECTION).is_enabled() and driver.find_element_by_xpath(
                PROXY_DENIES_CONNECTION).is_displayed():
            print("Proxy denies connection")
            driver.quit()

        if driver.find_element_by_xpath(TIMEOUT_XPATH1).is_enabled() and driver.find_element_by_xpath(
                TIMEOUT_XPATH1).is_displayed():
            print("Time out detected")
            driver.quit()

        if driver.find_element_by_xpath(PLAY_BUTTON_XPATH).is_enabled() and driver.find_element_by_xpath(
                PLAY_BUTTON_XPATH).is_displayed():
            print("Agar.io server is loaded")
            break

        else:
            continue

mainfunction()

编辑:尝试和除外

def mainfunction():
    while True:
        print("Starting")
        try:
            if driver.find_element_by_xpath(PROXY_DENIES_CONNECTION).is_enabled() and driver.find_element_by_xpath(
                    PROXY_DENIES_CONNECTION).is_displayed():
                print("Proxy denies connection")
                driver.quit()
        except:
            continue
        try:
            if driver.find_element_by_xpath(TIMEOUT_XPATH1).is_enabled() and driver.find_element_by_xpath(
                    TIMEOUT_XPATH1).is_displayed():
                print("Time out detected")
                driver.quit()
        except:
            continue

        try:
            if driver.find_element_by_xpath(PLAY_BUTTON_XPATH).is_enabled() and driver.find_element_by_xpath(
                    PLAY_BUTTON_XPATH).is_displayed():
                print("Agar.io server is loaded")
                break
        except:
            continue

当我运行它时,只在无限循环中运行打印开始......

python selenium selenium-webdriver xpath
4个回答
0
投票

当你使用driver.find_element*.something()时,如果找不到元素,driver.find_element*将抛出。这就是你的第一个代码块的问题,所以用if检查无关紧要。你可以通过几种方式解决这个问题。

  1. try-except,你已经尝试过了。您尝试的问题是,显然您的一个或多个定位器无法正常工作。这就是你获得无限循环的原因。
  2. 使用.find_elements_*(注意复数)并检查非空列表。但是......这不会解决糟糕的定位器问题,它只是try-catch等的替代方案。 if len(driver.find_elements_by_xpath(PROXY_DENIES_CONNECTION)) # do something

其他说明:

  1. 当您只是在寻找ID时,请不要使用XPath,例如更换 driver.find_element_by_xpath('//*[@id="play"]') driver.find_element_by_id('play')
  2. .is_enabled()真的只对INPUT标签有用。在其他任何事情上,它几乎总是返回true
  3. .is_enabled()已经假设.is_displayed()所以不需要检查两者。
  4. 而不是使用字符串只存储定位器(而不是类型),存储元组并像driver.find_element(tuple)一样使用它。它将使您的代码更清晰,更灵活。有关更多信息,请参阅this answer

通过此反馈,您可以将代码简化为更类似于下面的内容。假设您的定位器都很好(并且没有IFRAMEs),这应该可行。

#locators
PLAY_BUTTON = (By.ID, 'play')
PROXY_DENIES_CONNECTION = (By.ID, 'errorLongContent')
TIMEOUT = (By.ID, 'errorTryAgain')

def mainfunction():
    print("Starting")
    while True:
        try:
            if driver.find_element(PROXY_DENIES_CONNECTION).is_displayed():
                print("Proxy denies connection")
                driver.quit()
        except:
            continue

        try:
            if driver.find_element(TIMEOUT).is_displayed():
                print("Time out detected")
                driver.quit()
        except:
            continue

        try:
            if driver.find_element(PLAY_BUTTON).is_displayed():
                print("Agar.io server is loaded")
                break
        except:
            continue

2
投票

我将你的if语句放在“try / except”语句中,它运行时没有上面提到的错误。

from selenium import webdriver
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options

# Setup browser for
options = Options()
profile = webdriver.FirefoxProfile()
driver = Firefox(executable_path='geckodriver', options=options, firefox_profile=profile)
driver.get("https://agar.io")

#Xpaths
PLAY_BUTTON_XPATH = '//*[@id="play"]'
PROXY_DENIES_CONNECTION = '//*[@id="errorLongContent"]'
TIMEOUT_XPATH1 = '//*[@id="errorTryAgain"]'


#checking for error
def mainfunction():
    while True:
        print("Starting")
        try:
            if driver.find_element_by_xpath(PROXY_DENIES_CONNECTION).is_enabled() and driver.find_element_by_xpath(
                    PROXY_DENIES_CONNECTION).is_displayed():
                print("Proxy denies connection")
                driver.quit()
        except:
            pass
        try:
            if driver.find_element_by_xpath(TIMEOUT_XPATH1).is_enabled() and driver.find_element_by_xpath(
                    TIMEOUT_XPATH1).is_displayed():
                print("Time out detected")
                driver.quit()
        except:
            pass
        try:
            if driver.find_element_by_xpath(PLAY_BUTTON_XPATH).is_enabled() and driver.find_element_by_xpath(
                    PLAY_BUTTON_XPATH).is_displayed():
                print("Agar.io server is loaded")
                break
        except:
            pass

        else:
            continue

mainfunction()

2
投票

isDisplayed()的存在是为了告诉您页面上是否显示已经找到的元素;即,它的宽度和高度是否大于零,它不会被CSS等隐藏。如果该元素出现在页面上,但是style =“display:none;”那么isDisplayed()将返回false。

如果元素不存在那么它会抛出NoSuchElementException,所以你不能使用if和else而是使用try和expect。

def mainfunction():
    while True:
        print("Starting")
        try:
            if driver.find_element_by_xpath(PROXY_DENIES_CONNECTION).is_enabled() and driver.find_element_by_xpath(
                    PROXY_DENIES_CONNECTION).is_displayed():
                print("Proxy denies connection")
                driver.quit()

            if driver.find_element_by_xpath(TIMEOUT_XPATH1).is_enabled() and driver.find_element_by_xpath(
                    TIMEOUT_XPATH1).is_displayed():
                print("Time out detected")
                driver.quit()

            if driver.find_element_by_xpath(PLAY_BUTTON_XPATH).is_enabled() and driver.find_element_by_xpath(
                    PLAY_BUTTON_XPATH).is_displayed():
                print("Agar.io server is loaded")
                break
        except NoSuchElementException:
            continue

正如你所提到的,你的代码遇到了一个无限循环,因为它停留在while循环中(即从不执行driver.quit()或break语句)。当isDisplay抛出一个异常,然后流程转到包含continue语句的expect块。


2
投票

您似乎只想要加载特定按钮。那这个呢:

 while True:
    print("Starting")
    try:
        if driver.find_element_by_xpath(PLAY_BUTTON_XPATH).is_enabled() and driver.find_element_by_xpath(
                PLAY_BUTTON_XPATH).is_displayed():
            print("Agar.io server is loaded")
            break
    except:
        print('button did not load yet! waiting for a second')
        time.wait(1)
        continue

请注意,这将永远等待按钮到达!

© www.soinside.com 2019 - 2024. All rights reserved.