Сценарий Selenium Continue, если невозможно найти элемент - PullRequest
1 голос
/ 31 марта 2019

У меня проблема, когда я захожу на сайт, если хочу проверить, отображается ли элемент и включен ли он.Если это так, я хочу что-то напечатать.Если элемент не отображается и не включен, я хочу проверить наличие нового элемента, отображается ли этот элемент, если хотите что-то напечатать.Я надеюсь, что вы поняли.

При посещении веб-сайта и если первый оператор IF НЕ обнаруживается / отображается, он выдает ошибку и вместо перехода к следующему оператору If.

ОШИБКА:

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

Я уже пытался использовать команду try, ожидаем и изменил выражение 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 ]

2 голосов
/ 31 марта 2019

Кажется, вы ищете только определенную кнопку для загрузки. Как насчет этого:

 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 голосов
/ 31 марта 2019

isDisplayed () существует, чтобы сообщить вам, виден ли уже найденный элемент на странице;то есть, если его ширина и высота больше нуля, он не скрыт CSS и т. д. Если элемент присутствует на странице, но имеет style = "display: none;"тогда isDisplayed () вернет false.

И если элемент отсутствует, он генерирует исключение NoSuchElementException, так что вы не можете использовать if и else Вместо этого используйте try и Ожидайте.

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.

2 голосов
/ 31 марта 2019

Я поместил ваши операторы if в оператор "try / исключением", и он работает без указанной выше ошибки.

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()
0 голосов
/ 02 апреля 2019

Когда вы используете 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. Не используйте XPath, когда вы просто ищете ID, например, замените

    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).Это сделает ваш код намного чище и гибче.См. этот ответ для получения дополнительной информации.

С помощью этой обратной связи вы можете упростить свой код до чего-то более подобного приведенному ниже.Предполагая, что ваши локаторы все в порядке (и не 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...