Selenium Continue脚本(如果无法找到元素

时间:2019-03-31 18:24:26

标签: python selenium selenium-webdriver xpath

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

在访问网站时,未检测到/未显示第一个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

当我运行它时,它会无限循环地运行,仅打印正在启动...

4 个答案:

答案 0 :(得分:2)

我将您的if语句放在“ try / except”语句中,并且该语句运行时没有上述错误。

<script>
    /*diasble the first link - not working*/
    function function2() {
        document.getElementById("table1").href = "#";
    }
    return false;
</script>

答案 1 :(得分: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

请注意,这将一直永远,直到按钮到达!

答案 2 :(得分:2)

isDisplayed()的存在可以告诉您是否已定位该元素, 在页面上可见;即它的宽度和高度是否大于零, 不会被CSS等隐藏。如果该元素存在于页面上,但具有style =“ display: none;”,则isDisplayed()将返回false。

如果元素不存在,则抛出NoSuchElementException,因此您不能使用if和else 而是使用try and Expect。

something = b++; //something should probably be a B. 

正如您所提到的,您的代码陷入了无限循环,因为它被卡在while循环内(即从不执行driver.quit()或break语句)。 由于isDisplay引发异常,然后流程转到包含continue语句的Expect块。

答案 3 :(得分: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

有了此反馈,您可以将代码简化为以下内容。假设您的定位器都很好(并且没有IFRAME的定位器),这应该可以工作。

#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